diff options
458 files changed, 6189 insertions, 4460 deletions
diff --git a/.clang-format b/.clang-format index 237fd9ce30..eba6d586f0 100644 --- a/.clang-format +++ b/.clang-format @@ -112,11 +112,11 @@ UseTab: Always --- ### C++ specific config ### Language: Cpp -Standard: Cpp03 +Standard: Cpp11 --- ### ObjC specific config ### Language: ObjC -Standard: Cpp03 +Standard: Cpp11 ObjCBlockIndentWidth: 4 # ObjCSpaceAfterProperty: false # ObjCSpaceBeforeProtocolList: true diff --git a/.travis.yml b/.travis.yml index 1434447409..25b7795e13 100644 --- a/.travis.yml +++ b/.travis.yml @@ -119,7 +119,7 @@ matrix: - name: Javascript export template (release, emscripten latest) stage: build - env: PLATFORM=javascript TOOLS=no TARGET=release CACHE_NAME=${PLATFORM}-emcc-latest EXTRA_ARGS="module_glslang_enabled=no" + env: PLATFORM=javascript TOOLS=no TARGET=release CACHE_NAME=${PLATFORM}-emcc-latest EXTRA_ARGS="use_closure_compiler=yes" os: linux compiler: clang addons: diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index bfe07d61c5..62d83b2e04 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -964,10 +964,10 @@ void _OS::print_all_textures_by_size() { List<_OSCoreBindImg> imgs; int total = 0; { - List<Ref<Resource> > rsrc; + List<Ref<Resource>> rsrc; ResourceCache::get_cached_resources(&rsrc); - for (List<Ref<Resource> >::Element *E = rsrc.front(); E; E = E->next()) { + for (List<Ref<Resource>>::Element *E = rsrc.front(); E; E = E->next()) { if (!E->get()->is_class("ImageTexture")) continue; @@ -998,13 +998,13 @@ void _OS::print_resources_by_type(const Vector<String> &p_types) { Map<String, int> type_count; - List<Ref<Resource> > resources; + List<Ref<Resource>> resources; ResourceCache::get_cached_resources(&resources); - List<Ref<Resource> > rsrc; + List<Ref<Resource>> rsrc; ResourceCache::get_cached_resources(&rsrc); - for (List<Ref<Resource> >::Element *E = rsrc.front(); E; E = E->next()) { + for (List<Ref<Resource>>::Element *E = rsrc.front(); E; E = E->next()) { Ref<Resource> r = E->get(); @@ -1633,7 +1633,7 @@ Vector<Vector3> _Geometry::clip_polygon(const Vector<Vector3> &p_points, const P Array _Geometry::merge_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b) { - Vector<Vector<Point2> > polys = Geometry::merge_polygons_2d(p_polygon_a, p_polygon_b); + Vector<Vector<Point2>> polys = Geometry::merge_polygons_2d(p_polygon_a, p_polygon_b); Array ret; @@ -1645,7 +1645,7 @@ Array _Geometry::merge_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vec Array _Geometry::clip_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b) { - Vector<Vector<Point2> > polys = Geometry::clip_polygons_2d(p_polygon_a, p_polygon_b); + Vector<Vector<Point2>> polys = Geometry::clip_polygons_2d(p_polygon_a, p_polygon_b); Array ret; @@ -1657,7 +1657,7 @@ Array _Geometry::clip_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vect Array _Geometry::intersect_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b) { - Vector<Vector<Point2> > polys = Geometry::intersect_polygons_2d(p_polygon_a, p_polygon_b); + Vector<Vector<Point2>> polys = Geometry::intersect_polygons_2d(p_polygon_a, p_polygon_b); Array ret; @@ -1669,7 +1669,7 @@ Array _Geometry::intersect_polygons_2d(const Vector<Vector2> &p_polygon_a, const Array _Geometry::exclude_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b) { - Vector<Vector<Point2> > polys = Geometry::exclude_polygons_2d(p_polygon_a, p_polygon_b); + Vector<Vector<Point2>> polys = Geometry::exclude_polygons_2d(p_polygon_a, p_polygon_b); Array ret; @@ -1681,7 +1681,7 @@ Array _Geometry::exclude_polygons_2d(const Vector<Vector2> &p_polygon_a, const V Array _Geometry::clip_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon) { - Vector<Vector<Point2> > polys = Geometry::clip_polyline_with_polygon_2d(p_polyline, p_polygon); + Vector<Vector<Point2>> polys = Geometry::clip_polyline_with_polygon_2d(p_polyline, p_polygon); Array ret; @@ -1693,7 +1693,7 @@ Array _Geometry::clip_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline Array _Geometry::intersect_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon) { - Vector<Vector<Point2> > polys = Geometry::intersect_polyline_with_polygon_2d(p_polyline, p_polygon); + Vector<Vector<Point2>> polys = Geometry::intersect_polyline_with_polygon_2d(p_polyline, p_polygon); Array ret; @@ -1705,7 +1705,7 @@ Array _Geometry::intersect_polyline_with_polygon_2d(const Vector<Vector2> &p_pol Array _Geometry::offset_polygon_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type) { - Vector<Vector<Point2> > polys = Geometry::offset_polygon_2d(p_polygon, p_delta, Geometry::PolyJoinType(p_join_type)); + Vector<Vector<Point2>> polys = Geometry::offset_polygon_2d(p_polygon, p_delta, Geometry::PolyJoinType(p_join_type)); Array ret; @@ -1717,7 +1717,7 @@ Array _Geometry::offset_polygon_2d(const Vector<Vector2> &p_polygon, real_t p_de Array _Geometry::offset_polyline_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) { - Vector<Vector<Point2> > polys = Geometry::offset_polyline_2d(p_polygon, p_delta, Geometry::PolyJoinType(p_join_type), Geometry::PolyEndType(p_end_type)); + Vector<Vector<Point2>> polys = Geometry::offset_polyline_2d(p_polygon, p_delta, Geometry::PolyJoinType(p_join_type), Geometry::PolyEndType(p_end_type)); Array ret; @@ -2344,10 +2344,10 @@ Error _Directory::change_dir(String p_dir) { ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory must be opened before use."); return d->change_dir(p_dir); } -String _Directory::get_current_dir(bool p_include_drive) { +String _Directory::get_current_dir() { ERR_FAIL_COND_V_MSG(!d, "", "Directory must be opened before use."); - return d->get_current_dir(p_include_drive); + return d->get_current_dir(); } Error _Directory::make_dir(String p_dir) { @@ -2444,7 +2444,7 @@ void _Directory::_bind_methods() { ClassDB::bind_method(D_METHOD("get_drive", "idx"), &_Directory::get_drive); ClassDB::bind_method(D_METHOD("get_current_drive"), &_Directory::get_current_drive); ClassDB::bind_method(D_METHOD("change_dir", "todir"), &_Directory::change_dir); - ClassDB::bind_method(D_METHOD("get_current_dir", "include_drive"), &_Directory::get_current_dir, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("get_current_dir"), &_Directory::get_current_dir); ClassDB::bind_method(D_METHOD("make_dir", "path"), &_Directory::make_dir); ClassDB::bind_method(D_METHOD("make_dir_recursive", "path"), &_Directory::make_dir_recursive); ClassDB::bind_method(D_METHOD("file_exists", "path"), &_Directory::file_exists); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index fc6419b7d8..3a5bd28ce8 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -572,7 +572,7 @@ public: int get_current_drive(); Error change_dir(String p_dir); // Can be relative or absolute, return false on success. - String get_current_dir(bool p_include_drive = true); // Return current dir location. + String get_current_dir(); // Return current dir location. Error make_dir(String p_dir); Error make_dir_recursive(String p_dir); diff --git a/core/callable.cpp b/core/callable.cpp index 4a5ae3a248..2bb9ab167b 100644 --- a/core/callable.cpp +++ b/core/callable.cpp @@ -78,6 +78,12 @@ StringName Callable::get_method() const { return method; } +CallableCustom *Callable::get_custom() const { + ERR_FAIL_COND_V_MSG(!is_custom(), NULL, + vformat("Can't get custom on non-CallableCustom \"%s\".", operator String())); + return custom; +} + uint32_t Callable::hash() const { if (is_custom()) { return custom->hash(); diff --git a/core/callable.h b/core/callable.h index cecf2264a3..7fa024dccd 100644 --- a/core/callable.h +++ b/core/callable.h @@ -84,6 +84,7 @@ public: Object *get_object() const; ObjectID get_object_id() const; StringName get_method() const; + CallableCustom *get_custom() const; uint32_t hash() const; diff --git a/core/class_db.cpp b/core/class_db.cpp index 35e216a58f..50c924bdd2 100644 --- a/core/class_db.cpp +++ b/core/class_db.cpp @@ -1401,7 +1401,7 @@ void ClassDB::get_extensions_for_type(const StringName &p_class, List<String> *p } } -HashMap<StringName, HashMap<StringName, Variant> > ClassDB::default_values; +HashMap<StringName, HashMap<StringName, Variant>> ClassDB::default_values; Set<StringName> ClassDB::default_values_cached; Variant ClassDB::class_get_default_property_value(const StringName &p_class, const StringName &p_property, bool *r_valid) { diff --git a/core/class_db.h b/core/class_db.h index 398eca9132..35bbe6b6f5 100644 --- a/core/class_db.h +++ b/core/class_db.h @@ -119,7 +119,7 @@ public: void *class_ptr; HashMap<StringName, MethodBind *> method_map; HashMap<StringName, int> constant_map; - HashMap<StringName, List<StringName> > enum_map; + HashMap<StringName, List<StringName>> enum_map; HashMap<StringName, MethodInfo> signal_map; List<PropertyInfo> property_list; #ifdef DEBUG_METHODS_ENABLED @@ -160,7 +160,7 @@ public: static void _add_class2(const StringName &p_class, const StringName &p_inherits); - static HashMap<StringName, HashMap<StringName, Variant> > default_values; + static HashMap<StringName, HashMap<StringName, Variant>> default_values; static Set<StringName> default_values_cached; public: diff --git a/core/compressed_translation.cpp b/core/compressed_translation.cpp index ed307fd3ac..0225524bc8 100644 --- a/core/compressed_translation.cpp +++ b/core/compressed_translation.cpp @@ -50,8 +50,8 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) { int size = Math::larger_prime(keys.size()); - Vector<Vector<Pair<int, CharString> > > buckets; - Vector<Map<uint32_t, int> > table; + Vector<Vector<Pair<int, CharString>>> buckets; + Vector<Map<uint32_t, int>> table; Vector<uint32_t> hfunc_table; Vector<_PHashTranslationCmp> compressed; @@ -109,7 +109,7 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) { for (int i = 0; i < size; i++) { - const Vector<Pair<int, CharString> > &b = buckets[i]; + const Vector<Pair<int, CharString>> &b = buckets[i]; Map<uint32_t, int> &t = table.write[i]; if (b.size() == 0) diff --git a/core/cowdata.h b/core/cowdata.h index 4fdcaf3cea..fba3f64899 100644 --- a/core/cowdata.h +++ b/core/cowdata.h @@ -82,24 +82,25 @@ private: } _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) +#if defined(__GNUC__) size_t o; size_t p; - if (_mul_overflow(p_elements, sizeof(T), &o)) { + if (__builtin_mul_overflow(p_elements, sizeof(T), &o)) { *out = 0; return false; } *out = next_power_of_2(o); - if (_add_overflow(o, static_cast<size_t>(32), &p)) return false; //no longer allocated here + if (__builtin_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 + // and hope for the best. *out = _get_alloc_size(p_elements); return true; #endif diff --git a/core/debugger/debugger_marshalls.cpp b/core/debugger/debugger_marshalls.cpp index 4bccf0805f..eb3a19506a 100644 --- a/core/debugger/debugger_marshalls.cpp +++ b/core/debugger/debugger_marshalls.cpp @@ -32,8 +32,8 @@ #include "core/io/marshalls.h" -#define CHECK_SIZE(arr, expected, what) ERR_FAIL_COND_V_MSG((uint32_t)arr.size() < (uint32_t)(expected), false, String("Malformed ") + what + " message from script debugger, message too short. Exptected size: " + itos(expected) + ", actual size: " + itos(arr.size())) -#define CHECK_END(arr, expected, what) ERR_FAIL_COND_V_MSG((uint32_t)arr.size() > (uint32_t)expected, false, String("Malformed ") + what + " message from script debugger, message too long. Exptected size: " + itos(expected) + ", actual size: " + itos(arr.size())) +#define CHECK_SIZE(arr, expected, what) ERR_FAIL_COND_V_MSG((uint32_t)arr.size() < (uint32_t)(expected), false, String("Malformed ") + what + " message from script debugger, message too short. Expected size: " + itos(expected) + ", actual size: " + itos(arr.size())) +#define CHECK_END(arr, expected, what) ERR_FAIL_COND_V_MSG((uint32_t)arr.size() > (uint32_t)expected, false, String("Malformed ") + what + " message from script debugger, message too long. Expected size: " + itos(expected) + ", actual size: " + itos(arr.size())) Array DebuggerMarshalls::ResourceUsage::serialize() { infos.sort(); diff --git a/core/debugger/local_debugger.cpp b/core/debugger/local_debugger.cpp index 913d3fc031..01e30fb621 100644 --- a/core/debugger/local_debugger.cpp +++ b/core/debugger/local_debugger.cpp @@ -262,14 +262,14 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { if (line.get_slice_count(" ") <= 1) { - const Map<int, Set<StringName> > &breakpoints = script_debugger->get_breakpoints(); + const Map<int, Set<StringName>> &breakpoints = script_debugger->get_breakpoints(); if (breakpoints.size() == 0) { print_line("No Breakpoints."); continue; } print_line("Breakpoint(s): " + itos(breakpoints.size())); - for (Map<int, Set<StringName> >::Element *E = breakpoints.front(); E; E = E->next()) { + for (Map<int, Set<StringName>>::Element *E = breakpoints.front(); E; E = E->next()) { print_line("\t" + String(E->value().front()->get()) + ":" + itos(E->key())); } diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp index 7952391a27..5f7ffb115c 100644 --- a/core/debugger/remote_debugger.cpp +++ b/core/debugger/remote_debugger.cpp @@ -887,7 +887,7 @@ RemoteDebugger::RemoteDebugger(Ref<RemoteDebuggerPeer> p_peer) { visual_profiler = memnew(VisualProfiler); _bind_profiler("visual", visual_profiler); - // Perfromance Profiler + // Performance Profiler Object *perf = Engine::get_singleton()->get_singleton_object("Performance"); if (perf) { performance_profiler = memnew(PerformanceProfiler(perf)); diff --git a/core/debugger/script_debugger.h b/core/debugger/script_debugger.h index d8ddf353bf..2273073bf4 100644 --- a/core/debugger/script_debugger.h +++ b/core/debugger/script_debugger.h @@ -45,7 +45,7 @@ class ScriptDebugger { int depth = -1; bool skip_breakpoints = false; - Map<int, Set<StringName> > breakpoints; + Map<int, Set<StringName>> breakpoints; ScriptLanguage *break_lang = NULL; Vector<StackInfo> error_stack_info; @@ -67,7 +67,7 @@ public: bool is_breakpoint(int p_line, const StringName &p_source) const; bool is_breakpoint_line(int p_line) const; void clear_breakpoints(); - const Map<int, Set<StringName> > &get_breakpoints() const { return breakpoints; } + const Map<int, Set<StringName>> &get_breakpoints() const { return breakpoints; } void debug(ScriptLanguage *p_lang, bool p_can_continue = true, bool p_is_error_breakpoint = false); ScriptLanguage *get_break_language() const; diff --git a/core/error_macros.h b/core/error_macros.h index e4d7609e04..8818dcbe77 100644 --- a/core/error_macros.h +++ b/core/error_macros.h @@ -502,11 +502,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li * * The current function returns `m_retval`. */ -#define ERR_FAIL_V(m_retval) \ - if (1) { \ - _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed, returning: " __STR(m_retval)); \ - return m_retval; \ - } else \ +#define ERR_FAIL_V(m_retval) \ + if (1) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed, returning: " _STR(m_retval)); \ + return m_retval; \ + } else \ ((void)0) /** @@ -515,11 +515,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li * * Prints `m_msg`, and the current function returns `m_retval`. */ -#define ERR_FAIL_V_MSG(m_retval, m_msg) \ - if (1) { \ - _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed, returning: " __STR(m_retval), DEBUG_STR(m_msg)); \ - return m_retval; \ - } else \ +#define ERR_FAIL_V_MSG(m_retval, m_msg) \ + if (1) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed, returning: " _STR(m_retval), DEBUG_STR(m_msg)); \ + return m_retval; \ + } else \ ((void)0) /** diff --git a/core/input_map.cpp b/core/input_map.cpp index b855e14e0d..8f18c082d6 100644 --- a/core/input_map.cpp +++ b/core/input_map.cpp @@ -99,9 +99,9 @@ List<StringName> InputMap::get_actions() const { return actions; } -List<Ref<InputEvent> >::Element *InputMap::_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength) const { +List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength) const { - for (List<Ref<InputEvent> >::Element *E = p_action.inputs.front(); E; E = E->next()) { + for (List<Ref<InputEvent>>::Element *E = p_action.inputs.front(); E; E = E->next()) { const Ref<InputEvent> e = E->get(); @@ -151,7 +151,7 @@ void InputMap::action_erase_event(const StringName &p_action, const Ref<InputEve ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'."); - List<Ref<InputEvent> >::Element *E = _find_event(input_map[p_action], p_event); + List<Ref<InputEvent>>::Element *E = _find_event(input_map[p_action], p_event); if (E) input_map[p_action].inputs.erase(E); } @@ -166,9 +166,9 @@ void InputMap::action_erase_events(const StringName &p_action) { Array InputMap::_get_action_list(const StringName &p_action) { Array ret; - const List<Ref<InputEvent> > *al = get_action_list(p_action); + const List<Ref<InputEvent>> *al = get_action_list(p_action); if (al) { - for (const List<Ref<InputEvent> >::Element *E = al->front(); E; E = E->next()) { + for (const List<Ref<InputEvent>>::Element *E = al->front(); E; E = E->next()) { ret.push_back(E->get()); } @@ -177,7 +177,7 @@ Array InputMap::_get_action_list(const StringName &p_action) { return ret; } -const List<Ref<InputEvent> > *InputMap::get_action_list(const StringName &p_action) { +const List<Ref<InputEvent>> *InputMap::get_action_list(const StringName &p_action) { const Map<StringName, Action>::Element *E = input_map.find(p_action); if (!E) @@ -205,7 +205,7 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str bool pressed; float strength; - List<Ref<InputEvent> >::Element *event = _find_event(E->get(), p_event, &pressed, &strength); + List<Ref<InputEvent>>::Element *event = _find_event(E->get(), p_event, &pressed, &strength); if (event != NULL) { if (p_pressed != NULL) *p_pressed = pressed; diff --git a/core/input_map.h b/core/input_map.h index 19d550af77..6039d915c9 100644 --- a/core/input_map.h +++ b/core/input_map.h @@ -47,7 +47,7 @@ public: struct Action { int id; float deadzone; - List<Ref<InputEvent> > inputs; + List<Ref<InputEvent>> inputs; }; private: @@ -55,7 +55,7 @@ private: mutable Map<StringName, Action> input_map; - List<Ref<InputEvent> >::Element *_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool *p_pressed = NULL, float *p_strength = NULL) const; + List<Ref<InputEvent>>::Element *_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool *p_pressed = NULL, float *p_strength = NULL) const; Array _get_action_list(const StringName &p_action); Array _get_actions(); @@ -77,7 +77,7 @@ public: void action_erase_event(const StringName &p_action, const Ref<InputEvent> &p_event); void action_erase_events(const StringName &p_action); - const List<Ref<InputEvent> > *get_action_list(const StringName &p_action); + const List<Ref<InputEvent>> *get_action_list(const StringName &p_action); bool event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action) const; bool event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool *p_pressed = NULL, float *p_strength = NULL) const; diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp index 531467ecd6..351e2941e8 100644 --- a/core/io/config_file.cpp +++ b/core/io/config_file.cpp @@ -107,7 +107,7 @@ bool ConfigFile::has_section_key(const String &p_section, const String &p_key) c void ConfigFile::get_sections(List<String> *r_sections) const { - for (OrderedHashMap<String, OrderedHashMap<String, Variant> >::ConstElement E = values.front(); E; E = E.next()) { + for (OrderedHashMap<String, OrderedHashMap<String, Variant>>::ConstElement E = values.front(); E; E = E.next()) { r_sections->push_back(E.key()); } } @@ -187,7 +187,7 @@ Error ConfigFile::save_encrypted_pass(const String &p_path, const String &p_pass Error ConfigFile::_internal_save(FileAccess *file) { - for (OrderedHashMap<String, OrderedHashMap<String, Variant> >::Element E = values.front(); E; E = E.next()) { + for (OrderedHashMap<String, OrderedHashMap<String, Variant>>::Element E = values.front(); E; E = E.next()) { if (E != values.front()) file->store_string("\n"); diff --git a/core/io/config_file.h b/core/io/config_file.h index 7efcb5a04c..39fc2ab412 100644 --- a/core/io/config_file.h +++ b/core/io/config_file.h @@ -40,7 +40,7 @@ class ConfigFile : public Reference { GDCLASS(ConfigFile, Reference); - OrderedHashMap<String, OrderedHashMap<String, Variant> > values; + OrderedHashMap<String, OrderedHashMap<String, Variant>> values; PackedStringArray _get_sections() const; PackedStringArray _get_section_keys(const String &p_section) const; diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp index fc318b3dd2..9e707678c0 100644 --- a/core/io/file_access_memory.cpp +++ b/core/io/file_access_memory.cpp @@ -35,12 +35,12 @@ #include "core/os/dir_access.h" #include "core/project_settings.h" -static Map<String, Vector<uint8_t> > *files = NULL; +static Map<String, Vector<uint8_t>> *files = NULL; void FileAccessMemory::register_file(String p_name, Vector<uint8_t> p_data) { if (!files) { - files = memnew((Map<String, Vector<uint8_t> >)); + files = memnew((Map<String, Vector<uint8_t>>)); } String name; @@ -89,7 +89,7 @@ Error FileAccessMemory::_open(const String &p_path, int p_mode_flags) { String name = fix_path(p_path); //name = DirAccess::normalize_path(name); - Map<String, Vector<uint8_t> >::Element *E = files->find(name); + Map<String, Vector<uint8_t>>::Element *E = files->find(name); ERR_FAIL_COND_V_MSG(!E, ERR_FILE_NOT_FOUND, "Can't find file '" + p_path + "'."); data = E->get().ptrw(); diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index ce7025de35..56f8f1ff91 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -350,7 +350,7 @@ Error HTTPClient::poll() { handshaking = true; } else { // We are already handshaking, which means we can use your already active SSL connection - ssl = static_cast<Ref<StreamPeerSSL> >(connection); + ssl = static_cast<Ref<StreamPeerSSL>>(connection); if (ssl.is_null()) { close(); status = STATUS_SSL_HANDSHAKE_ERROR; diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp index 4b864f0dd7..c29df07624 100644 --- a/core/io/multiplayer_api.cpp +++ b/core/io/multiplayer_api.cpp @@ -874,7 +874,8 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p if (method_id == UINT16_MAX && p_from->get_script_instance()) { method_id = p_from->get_script_instance()->get_rpc_method_id(p_name); } - ERR_FAIL_COND_MSG(method_id == UINT16_MAX, "Unable to take the `method_id` for the function:" + p_name + ". this can happen only if this method is not marked as `remote`."); + ERR_FAIL_COND_MSG(method_id == UINT16_MAX, + vformat("Unable to take the `method_id` for the function \"%s\" at path: \"%s\". This happens when the method is not marked as `remote`.", p_name, p_from->get_path())); if (method_id <= UINT8_MAX) { // The ID fits in 1 byte diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index efaf958949..452514a588 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -362,7 +362,7 @@ Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_name(const String return Ref<ResourceImporter>(); } -void ResourceFormatImporter::get_importers_for_extension(const String &p_extension, List<Ref<ResourceImporter> > *r_importers) { +void ResourceFormatImporter::get_importers_for_extension(const String &p_extension, List<Ref<ResourceImporter>> *r_importers) { for (int i = 0; i < importers.size(); i++) { List<String> local_exts; @@ -423,7 +423,7 @@ bool ResourceFormatImporter::are_import_settings_valid(const String &p_path) con String ResourceFormatImporter::get_import_settings_hash() const { - Vector<Ref<ResourceImporter> > sorted_importers = importers; + Vector<Ref<ResourceImporter>> sorted_importers = importers; sorted_importers.sort_custom<SortImporterByName>(); diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index 65c148f2ac..369efbe83c 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -54,7 +54,7 @@ class ResourceFormatImporter : public ResourceFormatLoader { bool operator()(const Ref<ResourceImporter> &p_a, const Ref<ResourceImporter> &p_b) const; }; - Vector<Ref<ResourceImporter> > importers; + Vector<Ref<ResourceImporter>> importers; public: static ResourceFormatImporter *get_singleton() { return singleton; } @@ -83,7 +83,7 @@ public: void remove_importer(const Ref<ResourceImporter> &p_importer) { importers.erase(p_importer); } Ref<ResourceImporter> get_importer_by_name(const String &p_name) const; Ref<ResourceImporter> get_importer_by_extension(const String &p_extension) const; - void get_importers_for_extension(const String &p_extension, List<Ref<ResourceImporter> > *r_importers); + void get_importers_for_extension(const String &p_extension, List<Ref<ResourceImporter>> *r_importers); bool are_import_settings_valid(const String &p_path) const; String get_import_settings_hash() const; @@ -125,7 +125,7 @@ public: virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL) = 0; - virtual Error import_group_file(const String &p_group_file, const Map<String, Map<StringName, Variant> > &p_source_file_options, const Map<String, String> &p_base_paths) { return ERR_UNAVAILABLE; } + virtual Error import_group_file(const String &p_group_file, const Map<String, Map<StringName, Variant>> &p_source_file_options, const Map<String, String> &p_base_paths) { return ERR_UNAVAILABLE; } virtual bool are_import_settings_valid(const String &p_path) const { return true; } virtual String get_import_settings_string() const { return String(); } }; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 5dca8b3b89..b150df5f40 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -1113,7 +1113,7 @@ void ResourceLoader::add_custom_loaders() { void ResourceLoader::remove_custom_loaders() { - Vector<Ref<ResourceFormatLoader> > custom_loaders; + Vector<Ref<ResourceFormatLoader>> custom_loaders; for (int i = 0; i < loader_count; ++i) { if (loader[i]->get_script_instance()) { custom_loaders.push_back(loader[i]); @@ -1159,7 +1159,7 @@ int ResourceLoader::thread_suspended_count = 0; int ResourceLoader::thread_load_max = 0; SelfList<Resource>::List ResourceLoader::remapped_list; -HashMap<String, Vector<String> > ResourceLoader::translation_remaps; +HashMap<String, Vector<String>> ResourceLoader::translation_remaps; HashMap<String, String> ResourceLoader::path_remaps; ResourceLoaderImport ResourceLoader::import = NULL; diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index ea89917a5f..5ba9e26858 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -90,7 +90,7 @@ private: static void *dep_err_notify_ud; static DependencyErrorNotify dep_err_notify; static bool abort_on_missing_resource; - static HashMap<String, Vector<String> > translation_remaps; + static HashMap<String, Vector<String>> translation_remaps; static HashMap<String, String> path_remaps; static String _path_remap(const String &p_path, bool *r_translation_remapped = NULL); diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp index 740aaf5cfa..80d2c5e471 100644 --- a/core/io/resource_saver.cpp +++ b/core/io/resource_saver.cpp @@ -256,7 +256,7 @@ void ResourceSaver::add_custom_savers() { void ResourceSaver::remove_custom_savers() { - Vector<Ref<ResourceFormatSaver> > custom_savers; + Vector<Ref<ResourceFormatSaver>> custom_savers; for (int i = 0; i < saver_count; ++i) { if (saver[i]->get_script_instance()) { custom_savers.push_back(saver[i]); diff --git a/core/list.h b/core/list.h index 6250cec598..5a7c9e572c 100644 --- a/core/list.h +++ b/core/list.h @@ -576,7 +576,7 @@ public: void sort() { - sort_custom<Comparator<T> >(); + sort_custom<Comparator<T>>(); } template <class C> @@ -657,7 +657,7 @@ public: idx++; } - SortArray<Element *, AuxiliaryComparator<C> > sort; + SortArray<Element *, AuxiliaryComparator<C>> sort; sort.sort(aux_buffer, s); _data->first = aux_buffer[0]; diff --git a/core/math/expression.cpp b/core/math/expression.cpp index 058673b681..04fda9d09a 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -1839,7 +1839,7 @@ Expression::ENode *Expression::_parse_expression() { } } - //consecutively do unary opeators + //consecutively do unary operators for (int i = expr_pos - 1; i >= next_op; i--) { OperatorNode *op = alloc_node<OperatorNode>(); diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp index 69c7abfd30..3e07e9253e 100644 --- a/core/math/geometry.cpp +++ b/core/math/geometry.cpp @@ -214,9 +214,9 @@ static bool _group_face(_FaceClassify *p_faces, int len, int p_index, int p_grou return true; } -Vector<Vector<Face3> > Geometry::separate_objects(Vector<Face3> p_array) { +Vector<Vector<Face3>> Geometry::separate_objects(Vector<Face3> p_array) { - Vector<Vector<Face3> > objects; + Vector<Vector<Face3>> objects; int len = p_array.size(); @@ -235,7 +235,7 @@ Vector<Vector<Face3> > Geometry::separate_objects(Vector<Face3> p_array) { bool error = _connect_faces(_fcptr, len, -1); - ERR_FAIL_COND_V_MSG(error, Vector<Vector<Face3> >(), "Invalid geometry."); + ERR_FAIL_COND_V_MSG(error, Vector<Vector<Face3>>(), "Invalid geometry."); // Group connected faces in separate objects. @@ -679,8 +679,8 @@ Vector<Face3> Geometry::wrap_geometry(Vector<Face3> p_array, real_t *p_error) { return wrapped_faces; } -Vector<Vector<Vector2> > Geometry::decompose_polygon_in_convex(Vector<Point2> polygon) { - Vector<Vector<Vector2> > decomp; +Vector<Vector<Vector2>> Geometry::decompose_polygon_in_convex(Vector<Point2> polygon) { + Vector<Vector<Vector2>> decomp; List<TriangulatorPoly> in_poly, out_poly; TriangulatorPoly inp; @@ -1076,7 +1076,7 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu r_size = Size2(results[best].max_w, results[best].max_h); } -Vector<Vector<Point2> > Geometry::_polypaths_do_operation(PolyBooleanOperation p_op, const Vector<Point2> &p_polypath_a, const Vector<Point2> &p_polypath_b, bool is_a_open) { +Vector<Vector<Point2>> Geometry::_polypaths_do_operation(PolyBooleanOperation p_op, const Vector<Point2> &p_polypath_a, const Vector<Point2> &p_polypath_b, bool is_a_open) { using namespace ClipperLib; @@ -1111,7 +1111,7 @@ Vector<Vector<Point2> > Geometry::_polypaths_do_operation(PolyBooleanOperation p clp.Execute(op, paths); // Works on closed polygons only. } // Have to scale points down now. - Vector<Vector<Point2> > polypaths; + Vector<Vector<Point2>> polypaths; for (Paths::size_type i = 0; i < paths.size(); ++i) { Vector<Vector2> polypath; @@ -1128,7 +1128,7 @@ Vector<Vector<Point2> > Geometry::_polypaths_do_operation(PolyBooleanOperation p return polypaths; } -Vector<Vector<Point2> > Geometry::_polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) { +Vector<Vector<Point2>> Geometry::_polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) { using namespace ClipperLib; @@ -1162,7 +1162,7 @@ Vector<Vector<Point2> > Geometry::_polypath_offset(const Vector<Point2> &p_polyp co.Execute(paths, p_delta * SCALE_FACTOR); // Inflate/deflate. // Have to scale points down now. - Vector<Vector<Point2> > polypaths; + Vector<Vector<Point2>> polypaths; for (Paths::size_type i = 0; i < paths.size(); ++i) { Vector<Vector2> polypath; diff --git a/core/math/geometry.h b/core/math/geometry.h index a94d00bf77..6453d16181 100644 --- a/core/math/geometry.h +++ b/core/math/geometry.h @@ -790,44 +790,44 @@ public: END_ROUND }; - static Vector<Vector<Point2> > merge_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) { + static Vector<Vector<Point2>> merge_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) { return _polypaths_do_operation(OPERATION_UNION, p_polygon_a, p_polygon_b); } - static Vector<Vector<Point2> > clip_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) { + static Vector<Vector<Point2>> clip_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) { return _polypaths_do_operation(OPERATION_DIFFERENCE, p_polygon_a, p_polygon_b); } - static Vector<Vector<Point2> > intersect_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) { + static Vector<Vector<Point2>> intersect_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) { return _polypaths_do_operation(OPERATION_INTERSECTION, p_polygon_a, p_polygon_b); } - static Vector<Vector<Point2> > exclude_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) { + static Vector<Vector<Point2>> exclude_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) { return _polypaths_do_operation(OPERATION_XOR, p_polygon_a, p_polygon_b); } - static Vector<Vector<Point2> > clip_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon) { + static Vector<Vector<Point2>> clip_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon) { return _polypaths_do_operation(OPERATION_DIFFERENCE, p_polyline, p_polygon, true); } - static Vector<Vector<Point2> > intersect_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon) { + static Vector<Vector<Point2>> intersect_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon) { return _polypaths_do_operation(OPERATION_INTERSECTION, p_polyline, p_polygon, true); } - static Vector<Vector<Point2> > offset_polygon_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type) { + static Vector<Vector<Point2>> offset_polygon_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type) { return _polypath_offset(p_polygon, p_delta, p_join_type, END_POLYGON); } - static Vector<Vector<Point2> > offset_polyline_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) { + static Vector<Vector<Point2>> offset_polyline_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) { - ERR_FAIL_COND_V_MSG(p_end_type == END_POLYGON, Vector<Vector<Point2> >(), "Attempt to offset a polyline like a polygon (use offset_polygon_2d instead)."); + ERR_FAIL_COND_V_MSG(p_end_type == END_POLYGON, Vector<Vector<Point2>>(), "Attempt to offset a polyline like a polygon (use offset_polygon_2d instead)."); return _polypath_offset(p_polygon, p_delta, p_join_type, p_end_type); } @@ -899,7 +899,7 @@ public: return (intersections & 1); } - static Vector<Vector<Face3> > separate_objects(Vector<Face3> p_array); + static Vector<Vector<Face3>> separate_objects(Vector<Face3> p_array); // Create a "wrap" that encloses the given geometry. static Vector<Face3> wrap_geometry(Vector<Face3> p_array, real_t *p_error = NULL); @@ -1004,7 +1004,7 @@ public: H.resize(k); return H; } - static Vector<Vector<Vector2> > decompose_polygon_in_convex(Vector<Point2> polygon); + static Vector<Vector<Vector2>> decompose_polygon_in_convex(Vector<Point2> polygon); static MeshData build_convex_mesh(const Vector<Plane> &p_planes); static Vector<Plane> build_sphere_planes(real_t p_radius, int p_lats, int p_lons, Vector3::Axis p_axis = Vector3::AXIS_Z); @@ -1015,8 +1015,8 @@ public: static void make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_result, Size2i &r_size); private: - static Vector<Vector<Point2> > _polypaths_do_operation(PolyBooleanOperation p_op, const Vector<Point2> &p_polypath_a, const Vector<Point2> &p_polypath_b, bool is_a_open = false); - static Vector<Vector<Point2> > _polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type); + static Vector<Vector<Point2>> _polypaths_do_operation(PolyBooleanOperation p_op, const Vector<Point2> &p_polypath_a, const Vector<Point2> &p_polypath_b, bool is_a_open = false); + static Vector<Vector<Point2>> _polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type); }; #endif diff --git a/core/math/random_pcg.h b/core/math/random_pcg.h index ac65ce3509..8fd5a056fa 100644 --- a/core/math/random_pcg.h +++ b/core/math/random_pcg.h @@ -37,10 +37,10 @@ #include "thirdparty/misc/pcg.h" -#if defined(__GNUC__) || (_llvm_has_builtin(__builtin_clz)) +#if defined(__GNUC__) #define CLZ32(x) __builtin_clz(x) #elif defined(_MSC_VER) -#include "intrin.h" +#include <intrin.h> static int __bsr_clz32(uint32_t x) { unsigned long index; _BitScanReverse(&index, x); @@ -50,11 +50,11 @@ static int __bsr_clz32(uint32_t x) { #else #endif -#if defined(__GNUC__) || (_llvm_has_builtin(__builtin_ldexp) && _llvm_has_builtin(__builtin_ldexpf)) +#if defined(__GNUC__) #define LDEXP(s, e) __builtin_ldexp(s, e) #define LDEXPF(s, e) __builtin_ldexpf(s, e) #else -#include "math.h" +#include <math.h> #define LDEXP(s, e) ldexp(s, e) #define LDEXPF(s, e) ldexp(s, e) #endif diff --git a/core/method_ptrcall.h b/core/method_ptrcall.h index 3db186ca69..d09242e2f1 100644 --- a/core/method_ptrcall.h +++ b/core/method_ptrcall.h @@ -192,7 +192,7 @@ struct PtrToArg<ObjectID> { #define MAKE_VECARG(m_type) \ template <> \ - struct PtrToArg<Vector<m_type> > { \ + struct PtrToArg<Vector<m_type>> { \ _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \ const Vector<m_type> *dvs = reinterpret_cast<const Vector<m_type> *>(p_ptr); \ Vector<m_type> ret; \ @@ -237,7 +237,7 @@ struct PtrToArg<ObjectID> { #define MAKE_VECARG_ALT(m_type, m_type_alt) \ template <> \ - struct PtrToArg<Vector<m_type_alt> > { \ + struct PtrToArg<Vector<m_type_alt>> { \ _FORCE_INLINE_ static Vector<m_type_alt> convert(const void *p_ptr) { \ const Vector<m_type> *dvs = reinterpret_cast<const Vector<m_type> *>(p_ptr); \ Vector<m_type_alt> ret; \ @@ -293,7 +293,7 @@ MAKE_VECARG_ALT(String, StringName); //for stuff that gets converted to Array vectors #define MAKE_VECARR(m_type) \ template <> \ - struct PtrToArg<Vector<m_type> > { \ + struct PtrToArg<Vector<m_type>> { \ _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \ const Array *arr = reinterpret_cast<const Array *>(p_ptr); \ Vector<m_type> ret; \ @@ -333,7 +333,7 @@ MAKE_VECARR(Plane); #define MAKE_DVECARR(m_type) \ template <> \ - struct PtrToArg<Vector<m_type> > { \ + struct PtrToArg<Vector<m_type>> { \ _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \ const Array *arr = reinterpret_cast<const Array *>(p_ptr); \ Vector<m_type> ret; \ @@ -402,7 +402,7 @@ MAKE_VECARR(Plane); MAKE_STRINGCONV_BY_REFERENCE(IP_Address); template <> -struct PtrToArg<Vector<Face3> > { +struct PtrToArg<Vector<Face3>> { _FORCE_INLINE_ static Vector<Face3> convert(const void *p_ptr) { const Vector<Vector3> *dvs = reinterpret_cast<const Vector<Vector3> *>(p_ptr); Vector<Face3> ret; diff --git a/core/oa_hash_map.h b/core/oa_hash_map.h index 182ed8b116..7ceba26be8 100644 --- a/core/oa_hash_map.h +++ b/core/oa_hash_map.h @@ -48,7 +48,7 @@ */ template <class TKey, class TValue, class Hasher = HashMapHasherDefault, - class Comparator = HashMapComparatorDefault<TKey> > + class Comparator = HashMapComparatorDefault<TKey>> class OAHashMap { private: diff --git a/core/ordered_hash_map.h b/core/ordered_hash_map.h index a10cf06b75..055e3e607e 100644 --- a/core/ordered_hash_map.h +++ b/core/ordered_hash_map.h @@ -45,7 +45,7 @@ */ template <class K, class V, class Hasher = HashMapHasherDefault, class Comparator = HashMapComparatorDefault<K>, uint8_t MIN_HASH_TABLE_POWER = 3, uint8_t RELATIONSHIP = 8> class OrderedHashMap { - typedef List<Pair<const K *, V> > InternalList; + typedef List<Pair<const K *, V>> InternalList; typedef HashMap<K, typename InternalList::Element *, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP> InternalMap; InternalList list; diff --git a/core/os/mutex.cpp b/core/os/mutex.cpp index 97297dca28..31a0dc2bfa 100644 --- a/core/os/mutex.cpp +++ b/core/os/mutex.cpp @@ -44,7 +44,7 @@ void _global_unlock() { template class MutexImpl<std::recursive_mutex>; template class MutexImpl<std::mutex>; -template class MutexLock<MutexImpl<std::recursive_mutex> >; -template class MutexLock<MutexImpl<std::mutex> >; +template class MutexLock<MutexImpl<std::recursive_mutex>>; +template class MutexLock<MutexImpl<std::mutex>>; #endif diff --git a/core/os/mutex.h b/core/os/mutex.h index 9033f0cb06..b44b1994de 100644 --- a/core/os/mutex.h +++ b/core/os/mutex.h @@ -76,8 +76,8 @@ using BinaryMutex = MutexImpl<std::mutex>; // Non-recursive, handle with care extern template class MutexImpl<std::recursive_mutex>; extern template class MutexImpl<std::mutex>; -extern template class MutexLock<MutexImpl<std::recursive_mutex> >; -extern template class MutexLock<MutexImpl<std::mutex> >; +extern template class MutexLock<MutexImpl<std::recursive_mutex>>; +extern template class MutexLock<MutexImpl<std::mutex>>; #else diff --git a/core/os/threaded_array_processor.h b/core/os/threaded_array_processor.h index 9dcd6ceece..00dc53286e 100644 --- a/core/os/threaded_array_processor.h +++ b/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()); for (int i = 0; i < threads.size(); i++) { - threads.write[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++) { diff --git a/core/project_settings.cpp b/core/project_settings.cpp index 3a21610331..36fb016448 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -652,7 +652,7 @@ Error ProjectSettings::save() { return save_custom(get_resource_path().plus_file("project.godot")); } -Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom, const String &p_custom_features) { +Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<String, List<String>> &props, const CustomMap &p_custom, const String &p_custom_features) { Error err; FileAccess *file = FileAccess::open(p_file, FileAccess::WRITE, &err); @@ -663,7 +663,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str int count = 0; - for (Map<String, List<String> >::Element *E = props.front(); E; E = E->next()) { + for (Map<String, List<String>>::Element *E = props.front(); E; E = E->next()) { for (List<String>::Element *F = E->get().front(); F; F = F->next()) { @@ -700,7 +700,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str file->store_32(count); //store how many properties are saved } - for (Map<String, List<String> >::Element *E = props.front(); E; E = E->next()) { + for (Map<String, List<String>>::Element *E = props.front(); E; E = E->next()) { for (List<String>::Element *F = E->get().front(); F; F = F->next()) { @@ -740,7 +740,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str return OK; } -Error ProjectSettings::_save_settings_text(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom, const String &p_custom_features) { +Error ProjectSettings::_save_settings_text(const String &p_file, const Map<String, List<String>> &props, const CustomMap &p_custom, const String &p_custom_features) { Error err; FileAccess *file = FileAccess::open(p_file, FileAccess::WRITE, &err); @@ -761,7 +761,7 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin file->store_string("custom_features=\"" + p_custom_features + "\"\n"); file->store_string("\n"); - for (Map<String, List<String> >::Element *E = props.front(); E; E = E->next()) { + for (Map<String, List<String>>::Element *E = props.front(); E; E = E->next()) { if (E != props.front()) file->store_string("\n"); @@ -838,7 +838,7 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust vclist.insert(vc); } - Map<String, List<String> > props; + Map<String, List<String>> props; for (Set<_VCSort>::Element *E = vclist.front(); E; E = E->next()) { diff --git a/core/project_settings.h b/core/project_settings.h index ed153bdc20..8695df560e 100644 --- a/core/project_settings.h +++ b/core/project_settings.h @@ -97,8 +97,8 @@ protected: Error _load_settings_binary(const String &p_path); Error _load_settings_text_or_binary(const String &p_text_path, const String &p_bin_path); - Error _save_settings_text(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom = CustomMap(), const String &p_custom_features = String()); - Error _save_settings_binary(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom = CustomMap(), const String &p_custom_features = String()); + Error _save_settings_text(const String &p_file, const Map<String, List<String>> &props, const CustomMap &p_custom = CustomMap(), const String &p_custom_features = String()); + Error _save_settings_binary(const String &p_file, const Map<String, List<String>> &props, const CustomMap &p_custom = CustomMap(), const String &p_custom_features = String()); Error _save_custom_bnd(const String &p_file); diff --git a/core/reference.h b/core/reference.h index fd42c4e537..6898bfec3b 100644 --- a/core/reference.h +++ b/core/reference.h @@ -285,7 +285,7 @@ public: #ifdef PTRCALL_ENABLED template <class T> -struct PtrToArg<Ref<T> > { +struct PtrToArg<Ref<T>> { _FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) { @@ -312,7 +312,7 @@ struct PtrToArg<const Ref<T> &> { #ifdef DEBUG_METHODS_ENABLED template <class T> -struct GetTypeInfo<Ref<T> > { +struct GetTypeInfo<Ref<T>> { static const Variant::Type VARIANT_TYPE = Variant::OBJECT; static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; diff --git a/core/resource.cpp b/core/resource.cpp index 2afc9e4042..e329a1574f 100644 --- a/core/resource.cpp +++ b/core/resource.cpp @@ -149,7 +149,7 @@ void Resource::reload_from_file() { } } -Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource> > &remap_cache) { +Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource>> &remap_cache) { List<PropertyInfo> plist; get_property_list(&plist); @@ -190,7 +190,7 @@ Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Res return res; } -void Resource::configure_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource> > &remap_cache) { +void Resource::configure_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource>> &remap_cache) { List<PropertyInfo> plist; get_property_list(&plist); @@ -455,7 +455,7 @@ Resource::~Resource() { HashMap<String, Resource *> ResourceCache::resources; #ifdef TOOLS_ENABLED -HashMap<String, HashMap<String, int> > ResourceCache::resource_path_cache; +HashMap<String, HashMap<String, int>> ResourceCache::resource_path_cache; #endif RWLock *ResourceCache::lock = NULL; @@ -512,7 +512,7 @@ Resource *ResourceCache::get(const String &p_path) { return *res; } -void ResourceCache::get_cached_resources(List<Ref<Resource> > *p_resources) { +void ResourceCache::get_cached_resources(List<Ref<Resource>> *p_resources) { lock->read_lock(); const String *K = NULL; diff --git a/core/resource.h b/core/resource.h index b30788010b..4b79a39d9d 100644 --- a/core/resource.h +++ b/core/resource.h @@ -103,8 +103,8 @@ public: int get_subindex() const; virtual Ref<Resource> duplicate(bool p_subresources = false) const; - Ref<Resource> duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource> > &remap_cache); - void configure_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource> > &remap_cache); + Ref<Resource> duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource>> &remap_cache); + void configure_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource>> &remap_cache); void set_local_to_scene(bool p_enable); bool is_local_to_scene() const; @@ -150,7 +150,7 @@ class ResourceCache { static RWLock *lock; static HashMap<String, Resource *> resources; #ifdef TOOLS_ENABLED - static HashMap<String, HashMap<String, int> > resource_path_cache; // each tscn has a set of resource paths and IDs + static HashMap<String, HashMap<String, int>> resource_path_cache; // each tscn has a set of resource paths and IDs static RWLock *path_cache_lock; #endif // TOOLS_ENABLED friend void unregister_core_types(); @@ -163,7 +163,7 @@ public: static bool has(const String &p_path); static Resource *get(const String &p_path); static void dump(const char *p_file = NULL, bool p_short = false); - static void get_cached_resources(List<Ref<Resource> > *p_resources); + static void get_cached_resources(List<Ref<Resource>> *p_resources); static int get_cached_resource_count(); }; diff --git a/core/script_language.cpp b/core/script_language.cpp index 428f363b17..c664563909 100644 --- a/core/script_language.cpp +++ b/core/script_language.cpp @@ -284,7 +284,7 @@ void ScriptServer::save_global_classes() { } //////////////////// -void ScriptInstance::get_property_state(List<Pair<StringName, Variant> > &state) { +void ScriptInstance::get_property_state(List<Pair<StringName, Variant>> &state) { List<PropertyInfo> pinfo; get_property_list(&pinfo); diff --git a/core/script_language.h b/core/script_language.h index f1b809425b..bb7d74dd83 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -192,7 +192,7 @@ public: virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = NULL) const = 0; virtual Object *get_owner() { return NULL; } - virtual void get_property_state(List<Pair<StringName, Variant> > &state); + virtual void get_property_state(List<Pair<StringName, Variant>> &state); virtual void get_method_list(List<MethodInfo> *p_list) const = 0; virtual bool has_method(const StringName &p_method) const = 0; @@ -375,7 +375,7 @@ public: virtual void get_recognized_extensions(List<String> *p_extensions) const = 0; virtual void get_public_functions(List<MethodInfo> *p_functions) const = 0; - virtual void get_public_constants(List<Pair<String, Variant> > *p_constants) const = 0; + virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const = 0; struct ProfilingInfo { StringName signature; diff --git a/core/translation.cpp b/core/translation.cpp index 17c23b86cd..7399fa5619 100644 --- a/core/translation.cpp +++ b/core/translation.cpp @@ -995,7 +995,7 @@ String TranslationServer::get_locale_name(const String &p_locale) const { Array TranslationServer::get_loaded_locales() const { Array locales; - for (const Set<Ref<Translation> >::Element *E = translations.front(); E; E = E->next()) { + for (const Set<Ref<Translation>>::Element *E = translations.front(); E; E = E->next()) { const Ref<Translation> &t = E->get(); ERR_FAIL_COND_V(t.is_null(), Array()); @@ -1072,7 +1072,7 @@ StringName TranslationServer::translate(const StringName &p_message) const { String lang = get_language_code(locale); bool near_match = false; - for (const Set<Ref<Translation> >::Element *E = translations.front(); E; E = E->next()) { + for (const Set<Ref<Translation>>::Element *E = translations.front(); E; E = E->next()) { const Ref<Translation> &t = E->get(); ERR_FAIL_COND_V(t.is_null(), p_message); String l = t->get_locale(); @@ -1105,7 +1105,7 @@ StringName TranslationServer::translate(const StringName &p_message) const { String fallback_lang = get_language_code(fallback); near_match = false; - for (const Set<Ref<Translation> >::Element *E = translations.front(); E; E = E->next()) { + for (const Set<Ref<Translation>>::Element *E = translations.front(); E; E = E->next()) { const Ref<Translation> &t = E->get(); ERR_FAIL_COND_V(t.is_null(), p_message); String l = t->get_locale(); diff --git a/core/translation.h b/core/translation.h index 0448ea56c5..b9e07fa2b1 100644 --- a/core/translation.h +++ b/core/translation.h @@ -71,7 +71,7 @@ class TranslationServer : public Object { String locale; String fallback; - Set<Ref<Translation> > translations; + Set<Ref<Translation>> translations; Ref<Translation> tool_translation; Map<String, String> locale_name_map; diff --git a/core/type_info.h b/core/type_info.h index 5dacf67de4..3b08ff3cae 100644 --- a/core/type_info.h +++ b/core/type_info.h @@ -174,7 +174,7 @@ MAKE_TYPE_INFO(IP_Address, Variant::STRING) template <> struct GetTypeInfo<ObjectID> { static const Variant::Type VARIANT_TYPE = Variant::INT; - static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; + static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_INT_IS_UINT64; static inline PropertyInfo get_class_info() { return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_INT_IS_OBJECTID); } @@ -201,7 +201,7 @@ struct GetTypeInfo<const Variant &> { #define MAKE_TEMPLATE_TYPE_INFO(m_template, m_type, m_var_type) \ template <> \ - struct GetTypeInfo<m_template<m_type> > { \ + struct GetTypeInfo<m_template<m_type>> { \ static const Variant::Type VARIANT_TYPE = m_var_type; \ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \ static inline PropertyInfo get_class_info() { \ diff --git a/core/typedefs.h b/core/typedefs.h index 5376b0718a..bafbffcded 100644 --- a/core/typedefs.h +++ b/core/typedefs.h @@ -37,60 +37,41 @@ * Basic definitions and simple functions to be used everywhere. */ +// Include first in case the platform needs to pre-define/include some things. #include "platform_config.h" +// Should be available everywhere. +#include "core/error_list.h" +#include "core/int_types.h" + +// Turn argument to string constant: +// https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html#Stringizing #ifndef _STR #define _STR(m_x) #m_x #define _MKSTR(m_x) _STR(m_x) #endif -//should always inline no matter what +// Should always inline no matter what. #ifndef _ALWAYS_INLINE_ - -#if defined(__GNUC__) && (__GNUC__ >= 4) -#define _ALWAYS_INLINE_ __attribute__((always_inline)) inline -#elif defined(__llvm__) +#if defined(__GNUC__) #define _ALWAYS_INLINE_ __attribute__((always_inline)) inline #elif defined(_MSC_VER) #define _ALWAYS_INLINE_ __forceinline #else #define _ALWAYS_INLINE_ inline #endif - #endif -//should always inline, except in some cases because it makes debugging harder +// Should always inline, except in debug builds because it makes debugging harder. #ifndef _FORCE_INLINE_ - #ifdef DISABLE_FORCED_INLINE #define _FORCE_INLINE_ inline #else #define _FORCE_INLINE_ _ALWAYS_INLINE_ #endif - #endif -//custom, gcc-safe offsetof, because gcc complains a lot. -template <class T> -T *_nullptr() { - T *t = NULL; - return t; -} - -#define OFFSET_OF(st, m) \ - ((size_t)((char *)&(_nullptr<st>()->m) - (char *)0)) -/** - * Some platforms (devices) don't define NULL - */ - -#ifndef NULL -#define NULL 0 -#endif - -/** - * Windows badly defines a lot of stuff we'll never use. Undefine it. - */ - +// Windows badly defines a lot of stuff we'll never use. Undefine it. #ifdef _WIN32 #undef min // override standard definition #undef max // override standard definition @@ -105,18 +86,11 @@ T *_nullptr() { #undef CONNECT_DEFERRED // override from Windows SDK, clashes with Object enum #endif -#include "core/int_types.h" - -#include "core/error_list.h" - -/** Generic ABS function, for math uses please use Math::abs */ - +// Generic ABS function, for math uses please use Math::abs. #ifndef ABS #define ABS(m_v) (((m_v) < 0) ? (-(m_v)) : (m_v)) #endif -#define ABSDIFF(x, y) (((x) < (y)) ? ((y) - (x)) : ((x) - (y))) - #ifndef SGN #define SGN(m_v) (((m_v) < 0) ? (-1.0) : (+1.0)) #endif @@ -133,49 +107,24 @@ T *_nullptr() { #define CLAMP(m_a, m_min, m_max) (((m_a) < (m_min)) ? (m_min) : (((m_a) > (m_max)) ? m_max : m_a)) #endif -/** Generic swap template */ +// Generic swap template. #ifndef SWAP - #define SWAP(m_x, m_y) __swap_tmpl((m_x), (m_y)) template <class T> inline void __swap_tmpl(T &x, T &y) { - T aux = x; x = y; y = aux; } +#endif // SWAP -#endif //swap - -/* clang-format off */ -#define HEX2CHR(m_hex) \ - ((m_hex >= '0' && m_hex <= '9') ? (m_hex - '0') : \ - ((m_hex >= 'A' && m_hex <= 'F') ? (10 + m_hex - 'A') : \ - ((m_hex >= 'a' && m_hex <= 'f') ? (10 + m_hex - 'a') : 0))) -/* clang-format on */ - -// Macro to check whether we are compiled by clang -// and we have a specific builtin -#if defined(__llvm__) && defined(__has_builtin) -#define _llvm_has_builtin(x) __has_builtin(x) -#else -#define _llvm_has_builtin(x) 0 -#endif - -#if (defined(__GNUC__) && (__GNUC__ >= 5)) || _llvm_has_builtin(__builtin_mul_overflow) -#define _mul_overflow __builtin_mul_overflow -#endif - -#if (defined(__GNUC__) && (__GNUC__ >= 5)) || _llvm_has_builtin(__builtin_add_overflow) -#define _add_overflow __builtin_add_overflow -#endif - -/** Function to find the next power of 2 to an integer */ +/* Functions to handle powers of 2 and shifting. */ +// Function to find the next power of 2 to an integer. static _FORCE_INLINE_ unsigned int next_power_of_2(unsigned int x) { - - if (x == 0) + if (x == 0) { return 0; + } --x; x |= x >> 1; @@ -187,8 +136,8 @@ static _FORCE_INLINE_ unsigned int next_power_of_2(unsigned int x) { return ++x; } +// Function to find the previous power of 2 to an integer. static _FORCE_INLINE_ unsigned int previous_power_of_2(unsigned int x) { - x |= x >> 1; x |= x >> 2; x |= x >> 4; @@ -197,40 +146,45 @@ static _FORCE_INLINE_ unsigned int previous_power_of_2(unsigned int x) { return x - (x >> 1); } +// Function to find the closest power of 2 to an integer. static _FORCE_INLINE_ unsigned int closest_power_of_2(unsigned int x) { - unsigned int nx = next_power_of_2(x); unsigned int px = previous_power_of_2(x); return (nx - x) > (x - px) ? px : nx; } -// We need this definition inside the function below. -static inline int get_shift_from_power_of_2(unsigned int p_pixel); +// Get a shift value from a power of 2. +static inline int get_shift_from_power_of_2(unsigned int p_bits) { + for (unsigned int i = 0; i < 32; i++) { + if (p_bits == (unsigned int)(1 << i)) { + return i; + } + } + + return -1; +} template <class T> static _FORCE_INLINE_ T nearest_power_of_2_templated(T x) { - --x; // The number of operations on x is the base two logarithm - // of the p_number of bits in the type. Add three to account + // of the number of bits in the type. Add three to account // for sizeof(T) being in bytes. size_t num = get_shift_from_power_of_2(sizeof(T)) + 3; - // If the compiler is smart, it unrolls this loop - // If its dumb, this is a bit slow. - for (size_t i = 0; i < num; i++) + // If the compiler is smart, it unrolls this loop. + // If it's dumb, this is a bit slow. + for (size_t i = 0; i < num; i++) { x |= x >> (1 << i); + } return ++x; } -/** Function to find the nearest (bigger) power of 2 to an integer */ - +// Function to find the nearest (bigger) power of 2 to an integer. static inline unsigned int nearest_shift(unsigned int p_number) { - for (int i = 30; i >= 0; i--) { - if (p_number & (1 << i)) return i + 1; } @@ -238,41 +192,20 @@ static inline unsigned int nearest_shift(unsigned int p_number) { return 0; } -/** get a shift value from a power of 2 */ -static inline int get_shift_from_power_of_2(unsigned int p_pixel) { - // return a GL_TEXTURE_SIZE_ENUM - - for (unsigned int i = 0; i < 32; i++) { - - if (p_pixel == (unsigned int)(1 << i)) - return i; - } - - return -1; -} - -/** Swap 16 bits value for endianness */ -#if defined(__GNUC__) || _llvm_has_builtin(__builtin_bswap16) +// Swap 16, 32 and 64 bits value for endianness. +#if defined(__GNUC__) #define BSWAP16(x) __builtin_bswap16(x) +#define BSWAP32(x) __builtin_bswap32(x) +#define BSWAP64(x) __builtin_bswap64(x) #else static inline uint16_t BSWAP16(uint16_t x) { return (x >> 8) | (x << 8); } -#endif -/** Swap 32 bits value for endianness */ -#if defined(__GNUC__) || _llvm_has_builtin(__builtin_bswap32) -#define BSWAP32(x) __builtin_bswap32(x) -#else static inline uint32_t BSWAP32(uint32_t x) { return ((x << 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x >> 24)); } -#endif -/** Swap 64 bits value for endianness */ -#if defined(__GNUC__) || _llvm_has_builtin(__builtin_bswap64) -#define BSWAP64(x) __builtin_bswap64(x) -#else static inline uint64_t BSWAP64(uint64_t x) { x = (x & 0x00000000FFFFFFFF) << 32 | (x & 0xFFFFFFFF00000000) >> 32; x = (x & 0x0000FFFF0000FFFF) << 16 | (x & 0xFFFF0000FFFF0000) >> 16; @@ -281,40 +214,24 @@ static inline uint64_t BSWAP64(uint64_t x) { } #endif -/** When compiling with RTTI, we can add an "extra" - * layer of safeness in many operations, so dynamic_cast - * is used besides casting by enum. - */ - +// Generic comparator used in Map, List, etc. template <class T> struct Comparator { - _ALWAYS_INLINE_ bool operator()(const T &p_a, const T &p_b) const { return (p_a < p_b); } }; +// Global lock macro, relies on the static Mutex::_global_mutex. void _global_lock(); void _global_unlock(); struct _GlobalLock { - _GlobalLock() { _global_lock(); } ~_GlobalLock() { _global_unlock(); } }; #define GLOBAL_LOCK_FUNCTION _GlobalLock _global_lock_; -#ifdef NO_SAFE_CAST -#define SAFE_CAST static_cast -#else -#define SAFE_CAST dynamic_cast -#endif - -#define MT_SAFE - -#define __STRX(m_index) #m_index -#define __STR(m_index) __STRX(m_index) - -#ifdef __GNUC__ +#if defined(__GNUC__) #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) #else @@ -330,14 +247,12 @@ struct _GlobalLock { #define _PRINTF_FORMAT_ATTRIBUTE_2_3 #endif -/** This is needed due to a strange OpenGL API that expects a pointer - * type for an argument that is actually an offset. - */ +// This is needed due to a strange OpenGL API that expects a pointer +// type for an argument that is actually an offset. #define CAST_INT_TO_UCHAR_PTR(ptr) ((uint8_t *)(uintptr_t)(ptr)) // Home-made index sequence trick, so it can be used everywhere without the costly include of std::tuple. // https://stackoverflow.com/questions/15014096/c-index-of-type-during-variadic-template-expansion - template <size_t... Is> struct IndexSequence {}; diff --git a/core/ustring.cpp b/core/ustring.cpp index 1d4d9c2dfd..da089dce40 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -1402,7 +1402,7 @@ String String::utf8(const char *p_utf8, int p_len) { bool String::parse_utf8(const char *p_utf8, int p_len) { -#define _UNICERROR(m_err) print_line("Unicode error: " + String(m_err)); +#define _UNICERROR(m_err) print_line("Unicode parsing error: " + String(m_err) + ". Is the string valid UTF-8?"); if (!p_utf8) return true; diff --git a/core/variant.cpp b/core/variant.cpp index b82602a5a4..d12a15ec9d 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -2325,31 +2325,31 @@ inline DA _convert_array_from_variant(const Variant &p_variant) { return _convert_array<DA, Array>(p_variant.operator Array()); } case Variant::PACKED_BYTE_ARRAY: { - return _convert_array<DA, Vector<uint8_t> >(p_variant.operator Vector<uint8_t>()); + return _convert_array<DA, Vector<uint8_t>>(p_variant.operator Vector<uint8_t>()); } case Variant::PACKED_INT32_ARRAY: { - return _convert_array<DA, Vector<int32_t> >(p_variant.operator Vector<int32_t>()); + return _convert_array<DA, Vector<int32_t>>(p_variant.operator Vector<int32_t>()); } case Variant::PACKED_INT64_ARRAY: { - return _convert_array<DA, Vector<int64_t> >(p_variant.operator Vector<int64_t>()); + return _convert_array<DA, Vector<int64_t>>(p_variant.operator Vector<int64_t>()); } case Variant::PACKED_FLOAT32_ARRAY: { - return _convert_array<DA, Vector<float> >(p_variant.operator Vector<float>()); + return _convert_array<DA, Vector<float>>(p_variant.operator Vector<float>()); } case Variant::PACKED_FLOAT64_ARRAY: { - return _convert_array<DA, Vector<double> >(p_variant.operator Vector<double>()); + return _convert_array<DA, Vector<double>>(p_variant.operator Vector<double>()); } case Variant::PACKED_STRING_ARRAY: { - return _convert_array<DA, Vector<String> >(p_variant.operator Vector<String>()); + return _convert_array<DA, Vector<String>>(p_variant.operator Vector<String>()); } case Variant::PACKED_VECTOR2_ARRAY: { - return _convert_array<DA, Vector<Vector2> >(p_variant.operator Vector<Vector2>()); + return _convert_array<DA, Vector<Vector2>>(p_variant.operator Vector<Vector2>()); } case Variant::PACKED_VECTOR3_ARRAY: { - return _convert_array<DA, Vector<Vector3> >(p_variant.operator Vector<Vector3>()); + return _convert_array<DA, Vector<Vector3>>(p_variant.operator Vector<Vector3>()); } case Variant::PACKED_COLOR_ARRAY: { - return _convert_array<DA, Vector<Color> >(p_variant.operator Vector<Color>()); + return _convert_array<DA, Vector<Color>>(p_variant.operator Vector<Color>()); } default: { return DA(); @@ -2370,21 +2370,21 @@ Variant::operator Vector<uint8_t>() const { if (type == PACKED_BYTE_ARRAY) return static_cast<PackedArrayRef<uint8_t> *>(_data.packed_array)->array; else - return _convert_array_from_variant<Vector<uint8_t> >(*this); + return _convert_array_from_variant<Vector<uint8_t>>(*this); } Variant::operator Vector<int32_t>() const { if (type == PACKED_INT32_ARRAY) return static_cast<PackedArrayRef<int32_t> *>(_data.packed_array)->array; else - return _convert_array_from_variant<Vector<int> >(*this); + return _convert_array_from_variant<Vector<int>>(*this); } Variant::operator Vector<int64_t>() const { if (type == PACKED_INT64_ARRAY) return static_cast<PackedArrayRef<int64_t> *>(_data.packed_array)->array; else - return _convert_array_from_variant<Vector<int64_t> >(*this); + return _convert_array_from_variant<Vector<int64_t>>(*this); } Variant::operator Vector<float>() const { @@ -2392,7 +2392,7 @@ Variant::operator Vector<float>() const { if (type == PACKED_FLOAT32_ARRAY) return static_cast<PackedArrayRef<float> *>(_data.packed_array)->array; else - return _convert_array_from_variant<Vector<float> >(*this); + return _convert_array_from_variant<Vector<float>>(*this); } Variant::operator Vector<double>() const { @@ -2400,7 +2400,7 @@ Variant::operator Vector<double>() const { if (type == PACKED_FLOAT64_ARRAY) return static_cast<PackedArrayRef<double> *>(_data.packed_array)->array; else - return _convert_array_from_variant<Vector<double> >(*this); + return _convert_array_from_variant<Vector<double>>(*this); } Variant::operator Vector<String>() const { @@ -2408,21 +2408,21 @@ Variant::operator Vector<String>() const { if (type == PACKED_STRING_ARRAY) return static_cast<PackedArrayRef<String> *>(_data.packed_array)->array; else - return _convert_array_from_variant<Vector<String> >(*this); + return _convert_array_from_variant<Vector<String>>(*this); } Variant::operator Vector<Vector3>() const { if (type == PACKED_VECTOR3_ARRAY) return static_cast<PackedArrayRef<Vector3> *>(_data.packed_array)->array; else - return _convert_array_from_variant<Vector<Vector3> >(*this); + return _convert_array_from_variant<Vector<Vector3>>(*this); } Variant::operator Vector<Vector2>() const { if (type == PACKED_VECTOR2_ARRAY) return static_cast<PackedArrayRef<Vector2> *>(_data.packed_array)->array; else - return _convert_array_from_variant<Vector<Vector2> >(*this); + return _convert_array_from_variant<Vector<Vector2>>(*this); } Variant::operator Vector<Color>() const { @@ -2430,7 +2430,7 @@ Variant::operator Vector<Color>() const { if (type == PACKED_COLOR_ARRAY) return static_cast<PackedArrayRef<Color> *>(_data.packed_array)->array; else - return _convert_array_from_variant<Vector<Color> >(*this); + return _convert_array_from_variant<Vector<Color>>(*this); } /* helpers */ diff --git a/core/variant_call.cpp b/core/variant_call.cpp index f00aad33fc..db7244a221 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -1526,8 +1526,11 @@ void Variant::get_method_list(List<MethodInfo> *p_list) const { PropertyInfo ret; #ifdef DEBUG_ENABLED ret.type = fd.return_type; - if (fd.returns) + if (fd.returns) { ret.name = "ret"; + if (fd.return_type == Variant::NIL) + ret.usage = PROPERTY_USAGE_NIL_IS_VARIANT; + } mi.return_val = ret; #endif diff --git a/core/vector.h b/core/vector.h index d3476679ff..51a73e4ae4 100644 --- a/core/vector.h +++ b/core/vector.h @@ -103,7 +103,7 @@ public: void sort() { - sort_custom<_DefaultComparator<T> >(); + sort_custom<_DefaultComparator<T>>(); } void ordered_insert(const T &p_val) { diff --git a/doc/classes/AnimatedSprite.xml b/doc/classes/AnimatedSprite.xml index 03c23b6fdd..b5c1d38ff9 100644 --- a/doc/classes/AnimatedSprite.xml +++ b/doc/classes/AnimatedSprite.xml @@ -61,8 +61,10 @@ If [code]true[/code], the [member animation] is currently playing. </member> <member name="shininess" type="float" setter="set_shininess" getter="get_shininess" default="1.0"> + Strength of the specular light effect of this [AnimatedSprite]. </member> <member name="specular_color" type="Color" setter="set_specular_color" getter="get_specular_color" default="Color( 1, 1, 1, 1 )"> + The color of the specular light effect. </member> <member name="speed_scale" type="float" setter="set_speed_scale" getter="get_speed_scale" default="1.0"> The animation speed is multiplied by this value. diff --git a/doc/classes/Animation.xml b/doc/classes/Animation.xml index 0926ef9855..09811d5617 100644 --- a/doc/classes/Animation.xml +++ b/doc/classes/Animation.xml @@ -14,7 +14,7 @@ animation.track_insert_key(track_index, 0.0, 0) animation.track_insert_key(track_index, 0.5, 100) [/codeblock] - Animations are just data containers, and must be added to nodes such as an [AnimationPlayer] to be played back. + Animations are just data containers, and must be added to nodes such as an [AnimationPlayer] to be played back. Animation tracks have different types, each with its own set of dedicated methods. Check [enum TrackType] to see available types. </description> <tutorials> <link>https://docs.godotengine.org/en/latest/tutorials/animation/index.html</link> @@ -39,6 +39,7 @@ <argument index="1" name="key_idx" type="int"> </argument> <description> + Returns the animation name at the key identified by [code]key_idx[/code]. The [code]track_idx[/code] must be the index of an Animation Track. </description> </method> <method name="animation_track_insert_key"> @@ -51,6 +52,7 @@ <argument index="2" name="animation" type="StringName"> </argument> <description> + Inserts a key with value [code]animation[/code] at the given [code]time[/code] (in seconds). The [code]track_idx[/code] must be the index of an Animation Track. </description> </method> <method name="animation_track_set_key_animation"> @@ -63,6 +65,7 @@ <argument index="2" name="animation" type="StringName"> </argument> <description> + Sets the key identified by [code]key_idx[/code] to value [code]animation[/code]. The [code]track_idx[/code] must be the index of an Animation Track. </description> </method> <method name="audio_track_get_key_end_offset" qualifiers="const"> @@ -73,6 +76,8 @@ <argument index="1" name="key_idx" type="int"> </argument> <description> + Returns the end offset of the key identified by [code]key_idx[/code]. The [code]track_idx[/code] must be the index of an Audio Track. + End offset is the number of seconds cut off at the ending of the audio stream. </description> </method> <method name="audio_track_get_key_start_offset" qualifiers="const"> @@ -83,6 +88,8 @@ <argument index="1" name="key_idx" type="int"> </argument> <description> + Returns the start offset of the key identified by [code]key_idx[/code]. The [code]track_idx[/code] must be the index of an Audio Track. + Start offset is the number of seconds cut off at the beginning of the audio stream. </description> </method> <method name="audio_track_get_key_stream" qualifiers="const"> @@ -93,6 +100,7 @@ <argument index="1" name="key_idx" type="int"> </argument> <description> + Returns the audio stream of the key identified by [code]key_idx[/code]. The [code]track_idx[/code] must be the index of an Audio Track. </description> </method> <method name="audio_track_insert_key"> @@ -109,6 +117,8 @@ <argument index="4" name="end_offset" type="float" default="0"> </argument> <description> + Inserts an Audio Track key at the given [code]time[/code] in seconds. The [code]track_idx[/code] must be the index of an Audio Track. + [code]stream[/code] is the [AudioStream] resource to play. [code]start_offset[/code] is the number of seconds cut off at the beginning of the audio stream, while [code]end_offset[/code] is at the ending. </description> </method> <method name="audio_track_set_key_end_offset"> @@ -121,6 +131,7 @@ <argument index="2" name="offset" type="float"> </argument> <description> + Sets the end offset of the key identified by [code]key_idx[/code] to value [code]offset[/code]. The [code]track_idx[/code] must be the index of an Audio Track. </description> </method> <method name="audio_track_set_key_start_offset"> @@ -133,6 +144,7 @@ <argument index="2" name="offset" type="float"> </argument> <description> + Sets the start offset of the key identified by [code]key_idx[/code] to value [code]offset[/code]. The [code]track_idx[/code] must be the index of an Audio Track. </description> </method> <method name="audio_track_set_key_stream"> @@ -145,6 +157,7 @@ <argument index="2" name="stream" type="Resource"> </argument> <description> + Sets the stream of the key identified by [code]key_idx[/code] to value [code]offset[/code]. The [code]track_idx[/code] must be the index of an Audio Track. </description> </method> <method name="bezier_track_get_key_in_handle" qualifiers="const"> @@ -155,6 +168,7 @@ <argument index="1" name="key_idx" type="int"> </argument> <description> + Returns the in handle of the key identified by [code]key_idx[/code]. The [code]track_idx[/code] must be the index of a Bezier Track. </description> </method> <method name="bezier_track_get_key_out_handle" qualifiers="const"> @@ -165,6 +179,7 @@ <argument index="1" name="key_idx" type="int"> </argument> <description> + Returns the out handle of the key identified by [code]key_idx[/code]. The [code]track_idx[/code] must be the index of a Bezier Track. </description> </method> <method name="bezier_track_get_key_value" qualifiers="const"> @@ -175,6 +190,7 @@ <argument index="1" name="key_idx" type="int"> </argument> <description> + Returns the value of the key identified by [code]key_idx[/code]. The [code]track_idx[/code] must be the index of a Bezier Track. </description> </method> <method name="bezier_track_insert_key"> @@ -191,6 +207,8 @@ <argument index="4" name="out_handle" type="Vector2" default="Vector2( 0, 0 )"> </argument> <description> + Inserts a Bezier Track key at the given [code]time[/code] in seconds. The [code]track_idx[/code] must be the index of a Bezier Track. + [code]in_handle[/code] is the left-side weight of the added Bezier curve point, [code]out_handle[/code] is the right-side one, while [code]value[/code] is the actual value at this point. </description> </method> <method name="bezier_track_interpolate" qualifiers="const"> @@ -201,6 +219,7 @@ <argument index="1" name="time" type="float"> </argument> <description> + Returns the interpolated value at the given [code]time[/code] (in seconds). The [code]track_idx[/code] must be the index of a Bezier Track. </description> </method> <method name="bezier_track_set_key_in_handle"> @@ -213,6 +232,7 @@ <argument index="2" name="in_handle" type="Vector2"> </argument> <description> + Sets the in handle of the key identified by [code]key_idx[/code] to value [code]in_handle[/code]. The [code]track_idx[/code] must be the index of a Bezier Track. </description> </method> <method name="bezier_track_set_key_out_handle"> @@ -225,6 +245,7 @@ <argument index="2" name="out_handle" type="Vector2"> </argument> <description> + Sets the out handle of the key identified by [code]key_idx[/code] to value [code]out_handle[/code]. The [code]track_idx[/code] must be the index of a Bezier Track. </description> </method> <method name="bezier_track_set_key_value"> @@ -237,6 +258,7 @@ <argument index="2" name="value" type="float"> </argument> <description> + Sets the value of the key identified by [code]key_idx[/code] to the given value. The [code]track_idx[/code] must be the index of a Bezier Track. </description> </method> <method name="clear"> @@ -675,6 +697,7 @@ <signals> <signal name="tracks_changed"> <description> + Emitted when there's a change in the list of tracks, e.g. tracks are added, moved or have changed paths. </description> </signal> </signals> @@ -689,10 +712,13 @@ Method tracks call functions with given arguments per key. </constant> <constant name="TYPE_BEZIER" value="3" enum="TrackType"> + Bezier tracks are used to interpolate a value using custom curves. They can also be used to animate sub-properties of vectors and colors (e.g. alpha value of a [Color]). </constant> <constant name="TYPE_AUDIO" value="4" enum="TrackType"> + Audio tracks are used to play an audio stream with either type of [AudioStreamPlayer]. The stream can be trimmed and previewed in the animation. </constant> <constant name="TYPE_ANIMATION" value="5" enum="TrackType"> + Animation tracks play animations in other [AnimationPlayer] nodes. </constant> <constant name="INTERPOLATION_NEAREST" value="0" enum="InterpolationType"> No interpolation (nearest value). @@ -713,6 +739,7 @@ Update at the keyframes. </constant> <constant name="UPDATE_CAPTURE" value="3" enum="UpdateMode"> + Same as linear interpolation, but also interpolates from the current value (i.e. dynamically at runtime) if the first key isn't at 0 seconds. </constant> </constants> </class> diff --git a/doc/classes/AnimationNodeBlendTree.xml b/doc/classes/AnimationNodeBlendTree.xml index 0befb79577..4a34d75ff9 100644 --- a/doc/classes/AnimationNodeBlendTree.xml +++ b/doc/classes/AnimationNodeBlendTree.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="AnimationNodeBlendTree" inherits="AnimationRootNode" version="4.0"> <brief_description> + [AnimationTree] node resource that contains many blend type nodes. </brief_description> <description> + This node may contain a sub-tree of any other blend type nodes, such as mix, blend2, blend3, one shot, etc. This is one of the most commonly used roots. </description> <tutorials> <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link> @@ -18,6 +20,7 @@ <argument index="2" name="position" type="Vector2" default="Vector2( 0, 0 )"> </argument> <description> + Adds an [AnimationNode] at the given [code]position[/code]. The [code]name[/code] is used to identify the created sub-node later. </description> </method> <method name="connect_node"> @@ -30,6 +33,7 @@ <argument index="2" name="output_node" type="StringName"> </argument> <description> + Connects the output of an [AnimationNode] as input for another [AnimationNode], at the input port specified by [code]input_index[/code]. </description> </method> <method name="disconnect_node"> @@ -40,6 +44,7 @@ <argument index="1" name="input_index" type="int"> </argument> <description> + Disconnects the node connected to the specified input. </description> </method> <method name="get_node" qualifiers="const"> @@ -48,6 +53,7 @@ <argument index="0" name="name" type="StringName"> </argument> <description> + Returns the sub-node with the specified [code]name[/code]. </description> </method> <method name="get_node_position" qualifiers="const"> @@ -56,6 +62,7 @@ <argument index="0" name="name" type="StringName"> </argument> <description> + Returns the position of the sub-node with the specified [code]name[/code]. </description> </method> <method name="has_node" qualifiers="const"> @@ -64,6 +71,7 @@ <argument index="0" name="name" type="StringName"> </argument> <description> + Returns [code]true[/code] if a sub-node with specified [code]name[/code] exists. </description> </method> <method name="remove_node"> @@ -72,6 +80,7 @@ <argument index="0" name="name" type="StringName"> </argument> <description> + Removes a sub-node. </description> </method> <method name="rename_node"> @@ -82,6 +91,7 @@ <argument index="1" name="new_name" type="StringName"> </argument> <description> + Changes the name of a sub-node. </description> </method> <method name="set_node_position"> @@ -92,25 +102,33 @@ <argument index="1" name="position" type="Vector2"> </argument> <description> + Modifies the position of a sub-node. </description> </method> </methods> <members> <member name="graph_offset" type="Vector2" setter="set_graph_offset" getter="get_graph_offset" default="Vector2( 0, 0 )"> + The global offset of all sub-nodes. </member> </members> <constants> <constant name="CONNECTION_OK" value="0"> + The connection was successful. </constant> <constant name="CONNECTION_ERROR_NO_INPUT" value="1"> + The input node is [code]null[/code]. </constant> <constant name="CONNECTION_ERROR_NO_INPUT_INDEX" value="2"> + The specified input port is out of range. </constant> <constant name="CONNECTION_ERROR_NO_OUTPUT" value="3"> + The output node is [code]null[/code]. </constant> <constant name="CONNECTION_ERROR_SAME_NODE" value="4"> + Input and output nodes are the same. </constant> <constant name="CONNECTION_ERROR_CONNECTION_EXISTS" value="5"> + The specified connection already exists. </constant> </constants> </class> diff --git a/doc/classes/AnimationNodeOneShot.xml b/doc/classes/AnimationNodeOneShot.xml index b6e4ed9c98..4ba0b82df6 100644 --- a/doc/classes/AnimationNodeOneShot.xml +++ b/doc/classes/AnimationNodeOneShot.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="AnimationNodeOneShot" inherits="AnimationNode" version="4.0"> <brief_description> + Plays an animation once in [AnimationNodeBlendTree]. </brief_description> <description> + A resource to add to an [AnimationNodeBlendTree]. This node will execute a sub-animation and return once it finishes. Blend times for fading in and out can be customized, as well as filters. </description> <tutorials> <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link> @@ -25,10 +27,13 @@ </methods> <members> <member name="autorestart" type="bool" setter="set_autorestart" getter="has_autorestart" default="false"> + If [code]true[/code], the sub-animation will restart automatically after finishing. </member> <member name="autorestart_delay" type="float" setter="set_autorestart_delay" getter="get_autorestart_delay" default="1.0"> + The delay after which the automatic restart is triggered, in seconds. </member> <member name="autorestart_random_delay" type="float" setter="set_autorestart_random_delay" getter="get_autorestart_random_delay" default="0.0"> + If [member autorestart] is [code]true[/code], a random additional delay (in seconds) between 0 and this value will be added to [member autorestart_delay]. </member> <member name="fadein_time" type="float" setter="set_fadein_time" getter="get_fadein_time" default="0.1"> </member> diff --git a/doc/classes/AnimationNodeOutput.xml b/doc/classes/AnimationNodeOutput.xml index f4bded2cd1..38b05eb650 100644 --- a/doc/classes/AnimationNodeOutput.xml +++ b/doc/classes/AnimationNodeOutput.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="AnimationNodeOutput" inherits="AnimationNode" version="4.0"> <brief_description> + Generic output node to be added to [AnimationNodeBlendTree]. </brief_description> <description> </description> diff --git a/doc/classes/AnimationNodeStateMachine.xml b/doc/classes/AnimationNodeStateMachine.xml index b647ff70b8..3b351a3345 100644 --- a/doc/classes/AnimationNodeStateMachine.xml +++ b/doc/classes/AnimationNodeStateMachine.xml @@ -183,6 +183,16 @@ Renames the given node. </description> </method> + <method name="replace_node"> + <return type="void"> + </return> + <argument index="0" name="name" type="StringName"> + </argument> + <argument index="1" name="node" type="AnimationNode"> + </argument> + <description> + </description> + </method> <method name="set_end_node"> <return type="void"> </return> diff --git a/doc/classes/AnimationNodeTimeScale.xml b/doc/classes/AnimationNodeTimeScale.xml index 229f9bbba2..5c2e6cb692 100644 --- a/doc/classes/AnimationNodeTimeScale.xml +++ b/doc/classes/AnimationNodeTimeScale.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="AnimationNodeTimeScale" inherits="AnimationNode" version="4.0"> <brief_description> + A time-scaling animation node to be used with [AnimationTree]. </brief_description> <description> + Allows scaling the speed of the animation (or reversing it) in any children nodes. Setting it to 0 will pause the animation. </description> <tutorials> <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link> diff --git a/doc/classes/AnimationNodeTimeSeek.xml b/doc/classes/AnimationNodeTimeSeek.xml index 5a9cbe4861..0fef106da5 100644 --- a/doc/classes/AnimationNodeTimeSeek.xml +++ b/doc/classes/AnimationNodeTimeSeek.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="AnimationNodeTimeSeek" inherits="AnimationNode" version="4.0"> <brief_description> + A time-seeking animation node to be used with [AnimationTree]. </brief_description> <description> + This node can be used to cause a seek command to happen to any sub-children of the graph. After setting the time, this value returns to -1. </description> <tutorials> <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link> diff --git a/doc/classes/AnimationNodeTransition.xml b/doc/classes/AnimationNodeTransition.xml index bf94fe0466..11250c5b17 100644 --- a/doc/classes/AnimationNodeTransition.xml +++ b/doc/classes/AnimationNodeTransition.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="AnimationNodeTransition" inherits="AnimationNode" version="4.0"> <brief_description> + A generic animation transition node for [AnimationTree]. </brief_description> <description> + Simple state machine for cases which don't require a more advanced [AnimationNodeStateMachine]. Animations can be connected to the inputs and transition times can be specified. </description> <tutorials> <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link> @@ -47,8 +49,10 @@ </methods> <members> <member name="input_count" type="int" setter="set_enabled_inputs" getter="get_enabled_inputs" default="0"> + The number of available input ports for this node. </member> <member name="xfade_time" type="float" setter="set_cross_fade_time" getter="get_cross_fade_time" default="0.0"> + Cross-fading time (in seconds) between each animation connected to the inputs. </member> </members> <constants> diff --git a/doc/classes/AnimationTree.xml b/doc/classes/AnimationTree.xml index 2a7db37eea..9642dd1c70 100644 --- a/doc/classes/AnimationTree.xml +++ b/doc/classes/AnimationTree.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="AnimationTree" inherits="Node" version="4.0"> <brief_description> + A node to be used for advanced animation transitions in an [AnimationPlayer]. </brief_description> <description> </description> @@ -15,6 +16,7 @@ <argument index="0" name="delta" type="float"> </argument> <description> + Manually advance the animations by the specified time (in seconds). </description> </method> <method name="get_root_motion_transform" qualifiers="const"> @@ -36,22 +38,29 @@ </methods> <members> <member name="active" type="bool" setter="set_active" getter="is_active" default="false"> + If [code]true[/code], the [AnimationTree] will be processing. </member> <member name="anim_player" type="NodePath" setter="set_animation_player" getter="get_animation_player" default="NodePath("")"> + The path to the [AnimationPlayer] used for animating. </member> <member name="process_mode" type="int" setter="set_process_mode" getter="get_process_mode" enum="AnimationTree.AnimationProcessMode" default="1"> + The process mode of this [AnimationTree]. See [enum AnimationProcessMode] for available modes. </member> <member name="root_motion_track" type="NodePath" setter="set_root_motion_track" getter="get_root_motion_track" default="NodePath("")"> </member> <member name="tree_root" type="AnimationNode" setter="set_tree_root" getter="get_tree_root"> + The root animation node of this [AnimationTree]. See [AnimationNode]. </member> </members> <constants> <constant name="ANIMATION_PROCESS_PHYSICS" value="0" enum="AnimationProcessMode"> + The animations will progress during the physics frame (i.e. [method Node._physics_process]). </constant> <constant name="ANIMATION_PROCESS_IDLE" value="1" enum="AnimationProcessMode"> + The animations will progress during the idle frame (i.e. [method Node._process]). </constant> <constant name="ANIMATION_PROCESS_MANUAL" value="2" enum="AnimationProcessMode"> + The animations will only progress manually (see [method advance]). </constant> </constants> </class> diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index 6401feb95c..20296bbf45 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -116,7 +116,7 @@ </description> </method> <method name="back"> - <return type="void"> + <return type="Variant"> </return> <description> Returns the last element of the array, or [code]null[/code] if the array is empty. @@ -213,7 +213,7 @@ </description> </method> <method name="front"> - <return type="void"> + <return type="Variant"> </return> <description> Returns the first element of the array, or [code]null[/code] if the array is empty. @@ -260,28 +260,28 @@ </description> </method> <method name="max"> - <return type="void"> + <return type="Variant"> </return> <description> Returns the maximum value contained in the array if all elements are of comparable types. If the elements can't be compared, [code]null[/code] is returned. </description> </method> <method name="min"> - <return type="void"> + <return type="Variant"> </return> <description> Returns the minimum value contained in the array if all elements are of comparable types. If the elements can't be compared, [code]null[/code] is returned. </description> </method> <method name="pop_back"> - <return type="void"> + <return type="Variant"> </return> <description> Removes and returns the last element of the array. Returns [code]null[/code] if the array is empty. </description> </method> <method name="pop_front"> - <return type="void"> + <return type="Variant"> </return> <description> Removes and returns the first element of the array. Returns [code]null[/code] if the array is empty. diff --git a/doc/classes/ArrayMesh.xml b/doc/classes/ArrayMesh.xml index 33b62054df..47abd2e996 100644 --- a/doc/classes/ArrayMesh.xml +++ b/doc/classes/ArrayMesh.xml @@ -70,6 +70,7 @@ <return type="void"> </return> <description> + Removes all surfaces from this [ArrayMesh]. </description> </method> <method name="get_blend_shape_count" qualifiers="const"> diff --git a/doc/classes/AudioEffectRecord.xml b/doc/classes/AudioEffectRecord.xml index 189e3c7059..4dac81322f 100644 --- a/doc/classes/AudioEffectRecord.xml +++ b/doc/classes/AudioEffectRecord.xml @@ -1,22 +1,26 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="AudioEffectRecord" inherits="AudioEffect" version="4.0"> <brief_description> + Audio effect used for recording sound from a microphone. </brief_description> <description> </description> <tutorials> + <link>https://docs.godotengine.org/en/latest/tutorials/audio/recording_with_microphone.html</link> </tutorials> <methods> <method name="get_recording" qualifiers="const"> <return type="AudioStreamSample"> </return> <description> + Returns the recorded sample. </description> </method> <method name="is_recording_active" qualifiers="const"> <return type="bool"> </return> <description> + Returns whether the recording is active or not. </description> </method> <method name="set_recording_active"> @@ -25,11 +29,13 @@ <argument index="0" name="record" type="bool"> </argument> <description> + If [code]true[/code], the sound will be recorded. Note that restarting the recording will remove the previously recorded sample. </description> </method> </methods> <members> <member name="format" type="int" setter="set_format" getter="get_format" enum="AudioStreamSample.Format" default="1"> + Specifies the format in which the sample will be recorded. See [enum AudioStreamSample.Format] for available formats. </member> </members> <constants> diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml index 2e4ca9677d..380e739f46 100644 --- a/doc/classes/BaseMaterial3D.xml +++ b/doc/classes/BaseMaterial3D.xml @@ -67,6 +67,7 @@ <argument index="1" name="texture" type="Texture2D"> </argument> <description> + Sets the texture for the slot specified by [code]param[/code]. See [enum TextureParam] for available slots. </description> </method> </methods> @@ -425,8 +426,10 @@ Represents the size of the [enum TextureParam] enum. </constant> <constant name="TEXTURE_FILTER_NEAREST" value="0" enum="TextureFilter"> + The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized. </constant> <constant name="TEXTURE_FILTER_LINEAR" value="1" enum="TextureFilter"> + The texture filter blends between the nearest four pixels. Use this for most cases where you want to avoid a pixelated style. </constant> <constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="2" enum="TextureFilter"> </constant> @@ -437,6 +440,7 @@ <constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC" value="5" enum="TextureFilter"> </constant> <constant name="TEXTURE_FILTER_MAX" value="6" enum="TextureFilter"> + Represents the size of the [enum TextureFilter] enum. </constant> <constant name="DETAIL_UV_1" value="0" enum="DetailUV"> Use [code]UV[/code] with the detail texture. @@ -445,22 +449,29 @@ Use [code]UV2[/code] with the detail texture. </constant> <constant name="TRANSPARENCY_DISABLED" value="0" enum="Transparency"> + The material will not use transparency. </constant> <constant name="TRANSPARENCY_ALPHA" value="1" enum="Transparency"> + The material will use the texture's alpha values for transparency. </constant> <constant name="TRANSPARENCY_ALPHA_SCISSOR" value="2" enum="Transparency"> </constant> <constant name="TRANSPARENCY_ALPHA_DEPTH_PRE_PASS" value="3" enum="Transparency"> </constant> <constant name="TRANSPARENCY_MAX" value="4" enum="Transparency"> + Represents the size of the [enum Transparency] enum. </constant> <constant name="SHADING_MODE_UNSHADED" value="0" enum="ShadingMode"> + The object will not receive shadows. </constant> <constant name="SHADING_MODE_PER_PIXEL" value="1" enum="ShadingMode"> + The object will be shaded per pixel. Useful for realistic shading effect. </constant> <constant name="SHADING_MODE_PER_VERTEX" value="2" enum="ShadingMode"> + The object will be shaded per vertex. Useful when you want cheaper shaders and do not care about visual quality. </constant> <constant name="SHADING_MODE_MAX" value="3" enum="ShadingMode"> + Represents the size of the [enum ShadingMode] enum. </constant> <constant name="FEATURE_EMISSION" value="0" enum="Feature"> Constant for setting [member emission_enabled]. diff --git a/doc/classes/Callable.xml b/doc/classes/Callable.xml index ec38128c1e..3cc74beb58 100644 --- a/doc/classes/Callable.xml +++ b/doc/classes/Callable.xml @@ -1,8 +1,20 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="Callable" version="4.0"> <brief_description> + An object representing a method in a certain object that can be called. </brief_description> <description> + [Callable] is a first class object which can be held in variables and passed to functions. It represents a given method in an [Object], and is typically used for signal callbacks. + [b]Example:[/b] + [codeblock] + var callable = Callable(self, "print_args") + func print_args(arg1, arg2, arg3 = ""): + prints(arg1, arg2, arg3) + func test(): + callable.call("hello", "world") # Prints "hello world". + callable.call(Vector2.UP, 42, callable) # Prints "(0, -1) 42 Node(Node.gd)::print_args". + callable.call("invalid") # Invalid call, should have at least 2 arguments. + [/codeblock] </description> <tutorials> </tutorials> @@ -15,36 +27,42 @@ <argument index="1" name="method_name" type="StringName"> </argument> <description> + Creates a new [Callable] for the method called [code]method_name[/code] in the specified [code]object[/code]. </description> </method> <method name="call" qualifiers="vararg"> <return type="Variant"> </return> <description> + Calls the method represented by this [Callable]. Arguments can be passed and should match the method's signature. </description> </method> <method name="call_deferred" qualifiers="vararg"> <return type="void"> </return> <description> + Calls the method represented by this [Callable] in deferred mode, i.e. during the idle frame. Arguments can be passed and should match the method's signature. </description> </method> <method name="get_method"> <return type="StringName"> </return> <description> + Returns the name of the method represented by this [Callable]. </description> </method> <method name="get_object"> <return type="Object"> </return> <description> + Returns the object on which this [Callable] is called. </description> </method> <method name="get_object_id"> <return type="int"> </return> <description> + Returns the ID of this [Callable]'s object (see [method Object.get_instance_id]). </description> </method> <method name="hash"> diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index dec7c907a4..73ba8b392f 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -656,10 +656,13 @@ The [CanvasItem] has exited the canvas. </constant> <constant name="TEXTURE_FILTER_PARENT_NODE" value="0" enum="TextureFilter"> + The [CanvasItem] will inherit the filter from its parent. </constant> <constant name="TEXTURE_FILTER_NEAREST" value="1" enum="TextureFilter"> + The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering. Useful for pixel art. </constant> <constant name="TEXTURE_FILTER_LINEAR" value="2" enum="TextureFilter"> + The texture filter blends between the nearest four pixels. Use this for most cases where you want to avoid a pixelated style. </constant> <constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="3" enum="TextureFilter"> </constant> @@ -670,16 +673,22 @@ <constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC" value="6" enum="TextureFilter"> </constant> <constant name="TEXTURE_FILTER_MAX" value="7" enum="TextureFilter"> + Represents the size of the [enum TextureFilter] enum. </constant> <constant name="TEXTURE_REPEAT_PARENT_NODE" value="0" enum="TextureRepeat"> + The [CanvasItem] will inherit the filter from its parent. </constant> <constant name="TEXTURE_REPEAT_DISABLED" value="1" enum="TextureRepeat"> + Texture will not repeat. </constant> <constant name="TEXTURE_REPEAT_ENABLED" value="2" enum="TextureRepeat"> + Texture will repeat normally. </constant> <constant name="TEXTURE_REPEAT_MIRROR" value="3" enum="TextureRepeat"> + Texture will repeat in a 2x2 tiled mode, where elements at even positions are mirrored. </constant> <constant name="TEXTURE_REPEAT_MAX" value="4" enum="TextureRepeat"> + Represents the size of the [enum TextureRepeat] enum. </constant> </constants> </class> diff --git a/doc/classes/CheckBox.xml b/doc/classes/CheckBox.xml index c29f089bce..9c42091eb8 100644 --- a/doc/classes/CheckBox.xml +++ b/doc/classes/CheckBox.xml @@ -4,7 +4,7 @@ Binary choice user interface widget. See also [CheckButton]. </brief_description> <description> - A checkbox allows the user to make a binary choice (choosing only one of two possible options). It's similar to [CheckButton] in functionality, but it has a different apperance. To follow established UX patterns, it's recommended to use CheckBox when toggling it has [b]no[/b] immediate effect on something. For instance, it should be used when toggling it will only do something once a confirmation button is pressed. + A checkbox allows the user to make a binary choice (choosing only one of two possible options). It's similar to [CheckButton] in functionality, but it has a different appearance. To follow established UX patterns, it's recommended to use CheckBox when toggling it has [b]no[/b] immediate effect on something. For instance, it should be used when toggling it will only do something once a confirmation button is pressed. </description> <tutorials> </tutorials> diff --git a/doc/classes/CheckButton.xml b/doc/classes/CheckButton.xml index 616940a494..514ff9a691 100644 --- a/doc/classes/CheckButton.xml +++ b/doc/classes/CheckButton.xml @@ -4,7 +4,7 @@ Checkable button. See also [CheckBox]. </brief_description> <description> - CheckButton is a toggle button displayed as a check field. It's similar to [CheckBox] in functionality, but it has a different apperance. To follow established UX patterns, it's recommended to use CheckButton when toggling it has an [b]immediate[/b] effect on something. For instance, it should be used if toggling it enables/disables a setting without requiring the user to press a confirmation button. + CheckButton is a toggle button displayed as a check field. It's similar to [CheckBox] in functionality, but it has a different appearance. To follow established UX patterns, it's recommended to use CheckButton when toggling it has an [b]immediate[/b] effect on something. For instance, it should be used if toggling it enables/disables a setting without requiring the user to press a confirmation button. </description> <tutorials> </tutorials> diff --git a/doc/classes/CollisionPolygon2D.xml b/doc/classes/CollisionPolygon2D.xml index e3135a4d0f..242cdb8c80 100644 --- a/doc/classes/CollisionPolygon2D.xml +++ b/doc/classes/CollisionPolygon2D.xml @@ -21,6 +21,7 @@ If [code]true[/code], only edges that face up, relative to [CollisionPolygon2D]'s rotation, will collide with other objects. </member> <member name="one_way_collision_margin" type="float" setter="set_one_way_collision_margin" getter="get_one_way_collision_margin" default="1.0"> + The margin used for one-way collision (in pixels). Higher values will make the shape thicker, and work better for colliders that enter the polygon at a high velocity. </member> <member name="polygon" type="PackedVector2Array" setter="set_polygon" getter="get_polygon" default="PackedVector2Array( )"> The polygon's list of vertices. The final point will be connected to the first. The returned value is a clone of the [PackedVector2Array], not a reference. diff --git a/doc/classes/CollisionShape2D.xml b/doc/classes/CollisionShape2D.xml index 4903f0d3a5..e32ce9c9f9 100644 --- a/doc/classes/CollisionShape2D.xml +++ b/doc/classes/CollisionShape2D.xml @@ -19,7 +19,7 @@ Sets whether this collision shape should only detect collision on one side (top or bottom). </member> <member name="one_way_collision_margin" type="float" setter="set_one_way_collision_margin" getter="get_one_way_collision_margin" default="1.0"> - The margin used for one-way collision (in pixels). + The margin used for one-way collision (in pixels). Higher values will make the shape thicker, and work better for colliders that enter the shape at a high velocity. </member> <member name="shape" type="Shape2D" setter="set_shape" getter="get_shape"> The actual shape owned by this collision shape. diff --git a/doc/classes/ColorPicker.xml b/doc/classes/ColorPicker.xml index 5ab929d911..d8b4a8f76c 100644 --- a/doc/classes/ColorPicker.xml +++ b/doc/classes/ColorPicker.xml @@ -88,26 +88,34 @@ </constants> <theme_items> <theme_item name="add_preset" type="Texture2D"> + The icon for the "Add Preset" button. </theme_item> <theme_item name="color_hue" type="Texture2D"> + Custom texture for the hue selection slider on the right. </theme_item> <theme_item name="color_sample" type="Texture2D"> </theme_item> <theme_item name="h_width" type="int" default="30"> + The width of the hue selection slider. </theme_item> <theme_item name="label_width" type="int" default="10"> </theme_item> <theme_item name="margin" type="int" default="4"> + The margin around the [ColorPicker]. </theme_item> <theme_item name="overbright_indicator" type="Texture2D"> + The indicator used to signalize that the color value is outside the 0-1 range. </theme_item> <theme_item name="preset_bg" type="Texture2D"> </theme_item> <theme_item name="screen_picker" type="Texture2D"> + The icon for the screen color picker button. </theme_item> <theme_item name="sv_height" type="int" default="256"> + The height of the saturation-value selection box. </theme_item> <theme_item name="sv_width" type="int" default="256"> + The width of the saturation-value selection box. </theme_item> </theme_items> </class> diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml index 062e72388f..540ebf3931 100644 --- a/doc/classes/Dictionary.xml +++ b/doc/classes/Dictionary.xml @@ -98,7 +98,7 @@ </description> </method> <method name="get"> - <return type="void"> + <return type="Variant"> </return> <argument index="0" name="key" type="Variant"> </argument> diff --git a/doc/classes/Directory.xml b/doc/classes/Directory.xml index cb59a69876..ed4257a809 100644 --- a/doc/classes/Directory.xml +++ b/doc/classes/Directory.xml @@ -77,11 +77,8 @@ <method name="get_current_dir"> <return type="String"> </return> - <argument index="0" name="include_drive" type="bool" default="true"> - </argument> <description> Returns the absolute path to the currently opened directory (e.g. [code]res://folder[/code] or [code]C:\tmp\folder[/code]). - On Windows, if [code]include_drive[/code] is [code]false[/code], the leading drive specificator is omitted from the returned value (e.g. [code]\tmp\folder[/code]). </description> </method> <method name="get_current_drive"> diff --git a/doc/classes/EditorExportPlugin.xml b/doc/classes/EditorExportPlugin.xml index da3840384e..8fac3e950d 100644 --- a/doc/classes/EditorExportPlugin.xml +++ b/doc/classes/EditorExportPlugin.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="EditorExportPlugin" inherits="Reference" version="4.0"> <brief_description> + A script that is executed when exporting projects. </brief_description> <description> </description> @@ -19,12 +20,14 @@ <argument index="3" name="flags" type="int"> </argument> <description> + Virtual method to be overridden by the user. It is called when the export starts and provides all information about the export. </description> </method> <method name="_export_end" qualifiers="virtual"> <return type="void"> </return> <description> + Virtual method to be overridden by the user. Called when the export is finished. </description> </method> <method name="_export_file" qualifiers="virtual"> diff --git a/doc/classes/EditorFileDialog.xml b/doc/classes/EditorFileDialog.xml index 2afdfde064..3e6bbd682d 100644 --- a/doc/classes/EditorFileDialog.xml +++ b/doc/classes/EditorFileDialog.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="EditorFileDialog" inherits="ConfirmationDialog" version="4.0"> <brief_description> + A modified version of [FileDialog] used by the editor. </brief_description> <description> </description> diff --git a/doc/classes/EditorFileSystem.xml b/doc/classes/EditorFileSystem.xml index a79c57e90f..30e1de1f5e 100644 --- a/doc/classes/EditorFileSystem.xml +++ b/doc/classes/EditorFileSystem.xml @@ -75,6 +75,7 @@ <return type="void"> </return> <description> + Scans the script files and updates the list of custom class names. </description> </method> </methods> diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml index 3dad948629..f5c04b3947 100644 --- a/doc/classes/Environment.xml +++ b/doc/classes/Environment.xml @@ -191,6 +191,7 @@ <member name="reflected_light_source" type="int" setter="set_reflection_source" getter="get_reflection_source" enum="Environment.ReflectionSource" default="0"> </member> <member name="sky" type="Sky" setter="set_sky" getter="get_sky"> + The [Sky] resource used for this [Environment]. </member> <member name="sky_custom_fov" type="float" setter="set_sky_custom_fov" getter="get_sky_custom_fov" default="0.0"> </member> diff --git a/doc/classes/FileDialog.xml b/doc/classes/FileDialog.xml index f2c65a8610..78fcec33ea 100644 --- a/doc/classes/FileDialog.xml +++ b/doc/classes/FileDialog.xml @@ -133,16 +133,22 @@ </constants> <theme_items> <theme_item name="files_disabled" type="Color" default="Color( 0, 0, 0, 0.7 )"> + The color tint for disabled files (when the [FileDialog] is used in open folder mode). </theme_item> <theme_item name="folder" type="Texture2D"> + Custom icon for folders. </theme_item> <theme_item name="folder_icon_modulate" type="Color" default="Color( 1, 1, 1, 1 )"> + The color modulation applied to the folder icon. </theme_item> <theme_item name="parent_folder" type="Texture2D"> + Custom icon for the parent folder arrow. </theme_item> <theme_item name="reload" type="Texture2D"> + Custom icon for the reload button. </theme_item> <theme_item name="toggle_hidden" type="Texture2D"> + Custom icon for the toggle hidden button. </theme_item> </theme_items> </class> diff --git a/doc/classes/Font.xml b/doc/classes/Font.xml index 6543a3ecf1..882f819e37 100644 --- a/doc/classes/Font.xml +++ b/doc/classes/Font.xml @@ -85,6 +85,7 @@ <argument index="1" name="width" type="float"> </argument> <description> + Returns the size that the string would have with word wrapping enabled with a fixed [code]width[/code]. </description> </method> <method name="has_outline" qualifiers="const"> diff --git a/doc/classes/Geometry.xml b/doc/classes/Geometry.xml index b2d77f6f92..4d6f7b60a3 100644 --- a/doc/classes/Geometry.xml +++ b/doc/classes/Geometry.xml @@ -70,7 +70,7 @@ </argument> <description> Clips [code]polygon_a[/code] against [code]polygon_b[/code] and returns an array of clipped polygons. This performs [constant OPERATION_DIFFERENCE] between polygons. Returns an empty array if [code]polygon_b[/code] completely overlaps [code]polygon_a[/code]. - If [code]polygon_b[/code] is enclosed by [code]polygon_a[/code], returns an outer polygon (boundary) and inner polygon (hole) which could be distiguished by calling [method is_polygon_clockwise]. + If [code]polygon_b[/code] is enclosed by [code]polygon_a[/code], returns an outer polygon (boundary) and inner polygon (hole) which could be distinguished by calling [method is_polygon_clockwise]. </description> </method> <method name="clip_polyline_with_polygon_2d"> @@ -102,7 +102,7 @@ </argument> <description> Mutually excludes common area defined by intersection of [code]polygon_a[/code] and [code]polygon_b[/code] (see [method intersect_polygons_2d]) and returns an array of excluded polygons. This performs [constant OPERATION_XOR] between polygons. In other words, returns all but common area between polygons. - The operation may result in an outer polygon (boundary) and inner polygon (hole) produced which could be distiguished by calling [method is_polygon_clockwise]. + The operation may result in an outer polygon (boundary) and inner polygon (hole) produced which could be distinguished by calling [method is_polygon_clockwise]. </description> </method> <method name="get_closest_point_to_segment"> diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml index 543afb01ee..c41ffd4bff 100644 --- a/doc/classes/GraphEdit.xml +++ b/doc/classes/GraphEdit.xml @@ -303,26 +303,37 @@ <theme_item name="bezier_len_pos" type="int" default="80"> </theme_item> <theme_item name="bg" type="StyleBox"> + The background drawn under the grid. </theme_item> <theme_item name="grid_major" type="Color" default="Color( 1, 1, 1, 0.2 )"> + Color of major grid lines. </theme_item> <theme_item name="grid_minor" type="Color" default="Color( 1, 1, 1, 0.05 )"> + Color of minor grid lines. </theme_item> <theme_item name="minus" type="Texture2D"> + The icon for the zoom out button. </theme_item> <theme_item name="more" type="Texture2D"> + The icon for the zoom in button. </theme_item> <theme_item name="port_grab_distance_horizontal" type="int" default="48"> + The horizontal range within which a port can be grabbed (on both sides). </theme_item> <theme_item name="port_grab_distance_vertical" type="int" default="6"> + The vertical range within which a port can be grabbed (on both sides). </theme_item> <theme_item name="reset" type="Texture2D"> + The icon for the zoom reset button. </theme_item> <theme_item name="selection_fill" type="Color" default="Color( 1, 1, 1, 0.3 )"> + The fill color of the selection rectangle. </theme_item> <theme_item name="selection_stroke" type="Color" default="Color( 1, 1, 1, 0.8 )"> + The outline color of the selection rectangle. </theme_item> <theme_item name="snap" type="Texture2D"> + The icon for the snap toggle button. </theme_item> </theme_items> </class> diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml index a9f1b15443..33074536da 100644 --- a/doc/classes/GraphNode.xml +++ b/doc/classes/GraphNode.xml @@ -253,42 +253,59 @@ </constants> <theme_items> <theme_item name="breakpoint" type="StyleBox"> + The background used when [member overlay] is set to [constant OVERLAY_BREAKPOINT]. </theme_item> <theme_item name="close" type="Texture2D"> + The icon for the close button, visible when [member show_close] is enabled. </theme_item> <theme_item name="close_color" type="Color" default="Color( 0, 0, 0, 1 )"> + The color modulation applied to the close button icon. </theme_item> <theme_item name="close_offset" type="int" default="18"> + The vertical offset of the close button. </theme_item> <theme_item name="comment" type="StyleBox"> + The [StyleBox] used when [member comment] is enabled. </theme_item> <theme_item name="commentfocus" type="StyleBox"> + The [StyleBox] used when [member comment] is enabled and the [GraphNode] is focused. </theme_item> <theme_item name="defaultfocus" type="StyleBox"> </theme_item> <theme_item name="defaultframe" type="StyleBox"> </theme_item> <theme_item name="frame" type="StyleBox"> + The default background for [GraphNode]. </theme_item> <theme_item name="port" type="Texture2D"> + The icon used for representing ports. </theme_item> <theme_item name="port_offset" type="int" default="3"> + Horizontal offset for the ports. </theme_item> <theme_item name="position" type="StyleBox"> + The background used when [member overlay] is set to [constant OVERLAY_POSITION]. </theme_item> <theme_item name="resizer" type="Texture2D"> + The icon used for resizer, visible when [member resizable] is enabled. </theme_item> <theme_item name="resizer_color" type="Color" default="Color( 0, 0, 0, 1 )"> + The color modulation applied to the resizer icon. </theme_item> <theme_item name="selectedframe" type="StyleBox"> + The background used when the [GraphNode] is selected. </theme_item> <theme_item name="separation" type="int" default="1"> + The vertical distance between ports. </theme_item> <theme_item name="title_color" type="Color" default="Color( 0, 0, 0, 1 )"> + Color of the title text. </theme_item> <theme_item name="title_font" type="Font"> + Font used for the title text. </theme_item> <theme_item name="title_offset" type="int" default="20"> + Vertical offset of the title text. </theme_item> </theme_items> </class> diff --git a/doc/classes/GridContainer.xml b/doc/classes/GridContainer.xml index 4493ee8dc1..e13dc43104 100644 --- a/doc/classes/GridContainer.xml +++ b/doc/classes/GridContainer.xml @@ -20,8 +20,10 @@ </constants> <theme_items> <theme_item name="hseparation" type="int" default="4"> + The horizontal separation of children nodes. </theme_item> <theme_item name="vseparation" type="int" default="4"> + The vertical separation of children nodes. </theme_item> </theme_items> </class> diff --git a/doc/classes/HSeparator.xml b/doc/classes/HSeparator.xml index aa83b67934..5b418d6428 100644 --- a/doc/classes/HSeparator.xml +++ b/doc/classes/HSeparator.xml @@ -14,8 +14,10 @@ </constants> <theme_items> <theme_item name="separation" type="int" default="4"> + The height of the area covered by the separator. Effectively works like a minimum height. </theme_item> <theme_item name="separator" type="StyleBox"> + The style for the separator line. Works best with [StyleBoxLine]. </theme_item> </theme_items> </class> diff --git a/doc/classes/HSlider.xml b/doc/classes/HSlider.xml index be3c94e495..2738958058 100644 --- a/doc/classes/HSlider.xml +++ b/doc/classes/HSlider.xml @@ -14,16 +14,22 @@ </constants> <theme_items> <theme_item name="grabber" type="Texture2D"> + The texture for the grabber (the draggable element). </theme_item> <theme_item name="grabber_area" type="StyleBox"> + The background of the area to the left of the grabber. </theme_item> <theme_item name="grabber_disabled" type="Texture2D"> + The texture for the grabber when it's disabled. </theme_item> <theme_item name="grabber_highlight" type="Texture2D"> + The texture for the grabber when it's focused. </theme_item> <theme_item name="slider" type="StyleBox"> + The background for the whole slider. Determines the height of the [code]grabber_area[/code]. </theme_item> <theme_item name="tick" type="Texture2D"> + The texture for the ticks, visible when [member Slider.tick_count] is greater than 0. </theme_item> </theme_items> </class> diff --git a/doc/classes/HSplitContainer.xml b/doc/classes/HSplitContainer.xml index 0dd1f96602..f6e9f33c20 100644 --- a/doc/classes/HSplitContainer.xml +++ b/doc/classes/HSplitContainer.xml @@ -14,12 +14,15 @@ </constants> <theme_items> <theme_item name="autohide" type="int" default="1"> + Boolean value. If 1 ([code]true[/code]), the grabber will hide automatically when it isn't under the cursor. If 0 ([code]false[/code]), it's always visible. </theme_item> <theme_item name="bg" type="StyleBox"> </theme_item> <theme_item name="grabber" type="Texture2D"> + The icon used for the grabber drawn in the middle area. </theme_item> <theme_item name="separation" type="int" default="12"> + The space between sides of the container. </theme_item> </theme_items> </class> diff --git a/doc/classes/HingeJoint.xml b/doc/classes/HingeJoint.xml index 53fa74cace..0d1b6ff0e0 100644 --- a/doc/classes/HingeJoint.xml +++ b/doc/classes/HingeJoint.xml @@ -15,6 +15,7 @@ <argument index="0" name="flag" type="int" enum="HingeJoint.Flag"> </argument> <description> + Returns the value of the specified flag. </description> </method> <method name="get_param" qualifiers="const"> @@ -23,6 +24,7 @@ <argument index="0" name="param" type="int" enum="HingeJoint.Param"> </argument> <description> + Returns the value of the specified parameter. </description> </method> <method name="set_flag"> @@ -33,6 +35,7 @@ <argument index="1" name="enabled" type="bool"> </argument> <description> + If [code]true[/code], enables the specified flag. </description> </method> <method name="set_param"> @@ -43,6 +46,7 @@ <argument index="1" name="value" type="float"> </argument> <description> + Sets the value of the specified parameter. </description> </method> </methods> diff --git a/doc/classes/ImageTexture.xml b/doc/classes/ImageTexture.xml index 98eb42831b..1578783b8b 100644 --- a/doc/classes/ImageTexture.xml +++ b/doc/classes/ImageTexture.xml @@ -42,6 +42,7 @@ <argument index="1" name="immediate" type="bool" default="false"> </argument> <description> + Replaces the texture's data with a new [code]image[/code]. If [code]immediate[/code] is [code]true[/code], it will take effect immediately after the call. </description> </method> </methods> diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml index 557a63b1cc..0f212e7498 100644 --- a/doc/classes/Input.xml +++ b/doc/classes/Input.xml @@ -349,7 +349,8 @@ <argument index="0" name="enable" type="bool"> </argument> <description> - Whether to accumulate similar input events sent by the operating system. Enabled by default. + Enables or disables the accumulation of similar input events sent by the operating system. When input accumulation is enabled, all input events generated during a frame will be merged and emitted when the frame is done rendering. Therefore, this limits the number of input method calls per second to the rendering FPS. + Input accumulation is enabled by default. It can be disabled to get slightly more precise/reactive input at the cost of increased CPU usage. In applications where drawing freehand lines is required, input accumulation should generally be disabled while the user is drawing the line to get results that closely follow the actual input. </description> </method> <method name="start_joy_vibration"> diff --git a/doc/classes/InputEventGesture.xml b/doc/classes/InputEventGesture.xml index 9cacd3e6fd..861ec026cd 100644 --- a/doc/classes/InputEventGesture.xml +++ b/doc/classes/InputEventGesture.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="InputEventGesture" inherits="InputEventWithModifiers" version="4.0"> <brief_description> + Base class for touch control gestures. </brief_description> <description> </description> @@ -10,6 +11,7 @@ </methods> <members> <member name="position" type="Vector2" setter="set_position" getter="get_position" default="Vector2( 0, 0 )"> + The local gesture position relative to the [Viewport]. If used in [method Control._gui_input], the position is relative to the current [Control] that received this gesture. </member> </members> <constants> diff --git a/doc/classes/MultiMesh.xml b/doc/classes/MultiMesh.xml index 24b87f8e28..2a1d270990 100644 --- a/doc/classes/MultiMesh.xml +++ b/doc/classes/MultiMesh.xml @@ -125,8 +125,10 @@ Format of transform used to transform mesh, either 2D or 3D. </member> <member name="use_colors" type="bool" setter="set_use_colors" getter="is_using_colors" default="false"> + If [code]true[/code], the [MultiMesh] will use color data (see [member color_array]). </member> <member name="use_custom_data" type="bool" setter="set_use_custom_data" getter="is_using_custom_data" default="false"> + If [code]true[/code], the [MultiMesh] will use custom data (see [member custom_data_array]). </member> <member name="visible_instance_count" type="int" setter="set_visible_instance_count" getter="get_visible_instance_count" default="-1"> Limits the number of instances drawn, -1 draws all instances. Changing this does not change the sizes of the buffers. diff --git a/doc/classes/NavigationAgent.xml b/doc/classes/NavigationAgent.xml index f896bf6d15..c6c9abec13 100644 --- a/doc/classes/NavigationAgent.xml +++ b/doc/classes/NavigationAgent.xml @@ -124,7 +124,7 @@ The distance to search for other agents. </member> <member name="path_max_distance" type="float" setter="set_path_max_distance" getter="get_path_max_distance" default="3.0"> - The maximum distance the agent is allowed away from the ideal path to the final location. This can happen due to trying to avoid collisions. When the maximum distance is exceded, it recalculates the ideal path. + The maximum distance the agent is allowed away from the ideal path to the final location. This can happen due to trying to avoid collisions. When the maximum distance is exceeded, it recalculates the ideal path. </member> <member name="radius" type="float" setter="set_radius" getter="get_radius" default="1.0"> The radius of the agent. diff --git a/doc/classes/NavigationAgent2D.xml b/doc/classes/NavigationAgent2D.xml index 116db76cc5..5a9c31ef67 100644 --- a/doc/classes/NavigationAgent2D.xml +++ b/doc/classes/NavigationAgent2D.xml @@ -118,7 +118,7 @@ The distance to search for other agents. </member> <member name="path_max_distance" type="float" setter="set_path_max_distance" getter="get_path_max_distance" default="3.0"> - The maximum distance the agent is allowed away from the ideal path to the final location. This can happen due to trying to avoid collisions. When the maximum distance is exceded, it recalculates the ideal path. + The maximum distance the agent is allowed away from the ideal path to the final location. This can happen due to trying to avoid collisions. When the maximum distance is exceeded, it recalculates the ideal path. </member> <member name="radius" type="float" setter="set_radius" getter="get_radius" default="10.0"> The radius of the agent. diff --git a/doc/classes/NavigationRegion.xml b/doc/classes/NavigationRegion.xml index 41fac70654..a32ded2878 100644 --- a/doc/classes/NavigationRegion.xml +++ b/doc/classes/NavigationRegion.xml @@ -13,7 +13,7 @@ <return type="void"> </return> <description> - Bakes the [NavigationMesh]. The baking is done in a seperate thread because navigation baking is not a cheap operation. This can be done at runtime. When it is completed, it automatically sets the new [NavigationMesh]. + Bakes the [NavigationMesh]. The baking is done in a separate thread because navigation baking is not a cheap operation. This can be done at runtime. When it is completed, it automatically sets the new [NavigationMesh]. </description> </method> </methods> diff --git a/doc/classes/PackedDataContainerRef.xml b/doc/classes/PackedDataContainerRef.xml index 9e7ed59054..f0f59675de 100644 --- a/doc/classes/PackedDataContainerRef.xml +++ b/doc/classes/PackedDataContainerRef.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="PackedDataContainerRef" inherits="Reference" version="4.0"> <brief_description> + Reference version of [PackedDataContainer]. </brief_description> <description> </description> diff --git a/doc/classes/PacketPeerUDP.xml b/doc/classes/PacketPeerUDP.xml index aa5599a3fb..668655b725 100644 --- a/doc/classes/PacketPeerUDP.xml +++ b/doc/classes/PacketPeerUDP.xml @@ -25,7 +25,7 @@ </argument> <description> Calling this method connects this UDP peer to the given [code]host[/code]/[code]port[/code] pair. UDP is in reality connectionless, so this option only means that incoming packets from different addresses are automatically discarded, and that outgoing packets are always sent to the connected address (future calls to [method set_dest_address] are not allowed). This method does not send any data to the remote peer, to do that, use [method PacketPeer.put_var] or [method PacketPeer.put_packet] as usual. See also [UDPServer]. - Note: Connecting to the remote peer does not help to protect from malicious attacks like IP spoofing, etc. Think about using an encryption technique like SSL or DTLS if you feel like your application is transfering sensitive information. + Note: Connecting to the remote peer does not help to protect from malicious attacks like IP spoofing, etc. Think about using an encryption technique like SSL or DTLS if you feel like your application is transferring sensitive information. </description> </method> <method name="get_packet_ip" qualifiers="const"> diff --git a/doc/classes/Panel.xml b/doc/classes/Panel.xml index a96871ba28..a3f6a0be8f 100644 --- a/doc/classes/Panel.xml +++ b/doc/classes/Panel.xml @@ -14,6 +14,7 @@ </constants> <theme_items> <theme_item name="panel" type="StyleBox"> + The style of this [Panel]. </theme_item> </theme_items> </class> diff --git a/doc/classes/PanelContainer.xml b/doc/classes/PanelContainer.xml index 9803a8dc51..d39122c395 100644 --- a/doc/classes/PanelContainer.xml +++ b/doc/classes/PanelContainer.xml @@ -17,6 +17,7 @@ </constants> <theme_items> <theme_item name="panel" type="StyleBox"> + The style of [PanelContainer]'s background. </theme_item> </theme_items> </class> diff --git a/doc/classes/PhysicsServer.xml b/doc/classes/PhysicsServer.xml index c9f4accee2..1b9ce80a1b 100644 --- a/doc/classes/PhysicsServer.xml +++ b/doc/classes/PhysicsServer.xml @@ -1388,7 +1388,7 @@ </constant> <constant name="CONE_TWIST_JOINT_SWING_SPAN" value="0" enum="ConeTwistJointParam"> Swing is rotation from side to side, around the axis perpendicular to the twist axis. - The swing span defines, how much rotation will not get corrected allong the swing axis. + The swing span defines, how much rotation will not get corrected along the swing axis. Could be defined as looseness in the [ConeTwistJoint]. If below 0.05, this behavior is locked. </constant> diff --git a/doc/classes/PinJoint.xml b/doc/classes/PinJoint.xml index de4cb9d98a..78cab4805e 100644 --- a/doc/classes/PinJoint.xml +++ b/doc/classes/PinJoint.xml @@ -15,6 +15,7 @@ <argument index="0" name="param" type="int" enum="PinJoint.Param"> </argument> <description> + Returns the value of the specified parameter. </description> </method> <method name="set_param"> @@ -25,6 +26,7 @@ <argument index="1" name="value" type="float"> </argument> <description> + Sets the value of the specified parameter. </description> </method> </methods> diff --git a/doc/classes/Polygon2D.xml b/doc/classes/Polygon2D.xml index f777545733..13332ca4f0 100644 --- a/doc/classes/Polygon2D.xml +++ b/doc/classes/Polygon2D.xml @@ -17,12 +17,14 @@ <argument index="1" name="weights" type="PackedFloat32Array"> </argument> <description> + Adds a bone with the specified [code]path[/code] and [code]weights[/code]. </description> </method> <method name="clear_bones"> <return type="void"> </return> <description> + Removes all bones from this [Polygon2D]. </description> </method> <method name="erase_bone"> @@ -31,12 +33,14 @@ <argument index="0" name="index" type="int"> </argument> <description> + Removes the specified bone from this [Polygon2D]. </description> </method> <method name="get_bone_count" qualifiers="const"> <return type="int"> </return> <description> + Returns the number of bones in this [Polygon2D]. </description> </method> <method name="get_bone_path" qualifiers="const"> @@ -45,6 +49,7 @@ <argument index="0" name="index" type="int"> </argument> <description> + Returns the path to the node associated with the specified bone. </description> </method> <method name="get_bone_weights" qualifiers="const"> @@ -53,6 +58,7 @@ <argument index="0" name="index" type="int"> </argument> <description> + Returns the height values of the specified bone. </description> </method> <method name="set_bone_path"> @@ -63,6 +69,7 @@ <argument index="1" name="path" type="NodePath"> </argument> <description> + Sets the path to the node associated with the specified bone. </description> </method> <method name="set_bone_weights"> @@ -73,6 +80,7 @@ <argument index="1" name="weights" type="PackedFloat32Array"> </argument> <description> + Sets the weight values for the specified bone. </description> </method> </methods> diff --git a/doc/classes/PopupPanel.xml b/doc/classes/PopupPanel.xml index a3dd722f81..2e62d09f8f 100644 --- a/doc/classes/PopupPanel.xml +++ b/doc/classes/PopupPanel.xml @@ -14,6 +14,7 @@ </constants> <theme_items> <theme_item name="panel" type="StyleBox"> + The background panel style of this [PopupPanel]. </theme_item> </theme_items> </class> diff --git a/doc/classes/ProgressBar.xml b/doc/classes/ProgressBar.xml index e94299a5b8..c957d6f182 100644 --- a/doc/classes/ProgressBar.xml +++ b/doc/classes/ProgressBar.xml @@ -21,14 +21,19 @@ </constants> <theme_items> <theme_item name="bg" type="StyleBox"> + The style of the background. </theme_item> <theme_item name="fg" type="StyleBox"> + The style of the progress (i.e. the part that fills the bar). </theme_item> <theme_item name="font" type="Font"> + Font used to draw the fill percentage if [member percent_visible] is [code]true[/code]. </theme_item> <theme_item name="font_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> + The color of the text. </theme_item> <theme_item name="font_color_shadow" type="Color" default="Color( 0, 0, 0, 1 )"> + The color of the text's shadow. </theme_item> </theme_items> </class> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index af594c36d1..76674dcef8 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -824,16 +824,16 @@ </member> <member name="mono/unhandled_exception_policy" type="int" setter="" getter="" default="0"> </member> - <member name="network/limits/debugger/max_chars_per_second" type="int" setter="" getter="" default="2048"> + <member name="network/limits/debugger/max_chars_per_second" type="int" setter="" getter="" default="32768"> Maximum amount of characters allowed to send as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection. </member> - <member name="network/limits/debugger/max_errors_per_second" type="int" setter="" getter="" default="100"> + <member name="network/limits/debugger/max_errors_per_second" type="int" setter="" getter="" default="400"> Maximum number of errors allowed to be sent from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection. </member> - <member name="network/limits/debugger/max_queued_messages" type="int" setter="" getter="" default="10"> + <member name="network/limits/debugger/max_queued_messages" type="int" setter="" getter="" default="2048"> Maximum amount of messages in the debugger queue. Over this value, content is dropped. This helps to limit the debugger memory usage. </member> - <member name="network/limits/debugger/max_warnings_per_second" type="int" setter="" getter="" default="100"> + <member name="network/limits/debugger/max_warnings_per_second" type="int" setter="" getter="" default="400"> Maximum number of warnings allowed to be sent from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection. </member> <member name="network/limits/packet_peer_stream/max_buffer_po2" type="int" setter="" getter="" default="16"> diff --git a/doc/classes/ResourceLoader.xml b/doc/classes/ResourceLoader.xml index 533bc9ec28..1cf775f389 100644 --- a/doc/classes/ResourceLoader.xml +++ b/doc/classes/ResourceLoader.xml @@ -74,6 +74,8 @@ <argument index="0" name="path" type="String"> </argument> <description> + Returns the resource loaded by [method load_threaded_request]. + If this is called before the loading thread is done (i.e. [method load_threaded_get_status] is not [constant THREAD_LOAD_LOADED]), the calling thread will be blocked until the resource has finished loading. </description> </method> <method name="load_threaded_get_status"> @@ -84,6 +86,8 @@ <argument index="1" name="progress" type="Array" default="[ ]"> </argument> <description> + Returns the status of a threaded loading operation started with [method load_threaded_request] for the resource at [code]path[/code]. See [enum ThreadLoadStatus] for possible return values. + An array variable can optionally be passed via [code]progress[/code], and will return a one-element array containing the percentage of completion of the threaded loading. </description> </method> <method name="load_threaded_request"> @@ -96,6 +100,7 @@ <argument index="2" name="use_sub_threads" type="bool" default="false"> </argument> <description> + Loads the resource using threads. If [code]use_sub_threads[/code] is [code]true[/code], multiple threads will be used to load the resource, which makes loading faster, but may affect the main thread (and thus cause game slowdowns). </description> </method> <method name="set_abort_on_missing_resources"> @@ -110,12 +115,16 @@ </methods> <constants> <constant name="THREAD_LOAD_INVALID_RESOURCE" value="0" enum="ThreadLoadStatus"> + The resource is invalid, or has not been loaded with [method load_threaded_request]. </constant> <constant name="THREAD_LOAD_IN_PROGRESS" value="1" enum="ThreadLoadStatus"> + The resource is still being loaded. </constant> <constant name="THREAD_LOAD_FAILED" value="2" enum="ThreadLoadStatus"> + Some error occurred during loading and it failed. </constant> <constant name="THREAD_LOAD_LOADED" value="3" enum="ThreadLoadStatus"> + The resource was loaded successfully and can be accessed via [method load_threaded_get]. </constant> </constants> </class> diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index 5f07133a27..efc0c9d600 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -409,38 +409,55 @@ </constants> <theme_items> <theme_item name="bold_font" type="Font"> + The font used for bold text. </theme_item> <theme_item name="bold_italics_font" type="Font"> + The font used for bold italics text. </theme_item> <theme_item name="default_color" type="Color" default="Color( 1, 1, 1, 1 )"> + The default text color. </theme_item> <theme_item name="focus" type="StyleBox"> + The background The background used when the [RichTextLabel] is focused. </theme_item> <theme_item name="font_color_selected" type="Color" default="Color( 0.49, 0.49, 0.49, 1 )"> + The color of selected text, used when [member selection_enabled] is [code]true[/code]. </theme_item> <theme_item name="font_color_shadow" type="Color" default="Color( 0, 0, 0, 0 )"> + The color of the font's shadow. </theme_item> <theme_item name="italics_font" type="Font"> + The font used for italics text. </theme_item> <theme_item name="line_separation" type="int" default="1"> + The vertical space between lines. </theme_item> <theme_item name="mono_font" type="Font"> + The font used for monospace text. </theme_item> <theme_item name="normal" type="StyleBox"> + The normal background for the [RichTextLabel]. </theme_item> <theme_item name="normal_font" type="Font"> + The default text font. </theme_item> <theme_item name="selection_color" type="Color" default="Color( 0.1, 0.1, 1, 0.8 )"> + The color of the selection box. </theme_item> <theme_item name="shadow_as_outline" type="int" default="0"> + Boolean value. If 1 ([code]true[/code]), the shadow will be displayed around the whole text as an outline. </theme_item> <theme_item name="shadow_offset_x" type="int" default="1"> + The horizontal offset of the font's shadow. </theme_item> <theme_item name="shadow_offset_y" type="int" default="1"> + The vertical offset of the font's shadow. </theme_item> <theme_item name="table_hseparation" type="int" default="3"> + The horizontal separation of elements in a table. </theme_item> <theme_item name="table_vseparation" type="int" default="3"> + The vertical separation of elements in a table. </theme_item> </theme_items> </class> diff --git a/doc/classes/Script.xml b/doc/classes/Script.xml index f671315620..0d94453e52 100644 --- a/doc/classes/Script.xml +++ b/doc/classes/Script.xml @@ -38,30 +38,35 @@ <argument index="0" name="property" type="StringName"> </argument> <description> + Returns the default value of the specified property. </description> </method> <method name="get_script_constant_map"> <return type="Dictionary"> </return> <description> + Returns a dictionary containing constant names and their values. </description> </method> <method name="get_script_method_list"> <return type="Array"> </return> <description> + Returns the list of methods in this [Script]. </description> </method> <method name="get_script_property_list"> <return type="Array"> </return> <description> + Returns the list of properties in this [Script]. </description> </method> <method name="get_script_signal_list"> <return type="Array"> </return> <description> + Returns the list of user signals defined in this [Script]. </description> </method> <method name="has_script_signal" qualifiers="const"> diff --git a/doc/classes/ScriptEditor.xml b/doc/classes/ScriptEditor.xml index ed401d6853..10d6e5f578 100644 --- a/doc/classes/ScriptEditor.xml +++ b/doc/classes/ScriptEditor.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="ScriptEditor" inherits="PanelContainer" version="4.0"> <brief_description> + Godot editor's script editor. </brief_description> <description> </description> diff --git a/doc/classes/Signal.xml b/doc/classes/Signal.xml index 350ab40c0e..1a05c02b60 100644 --- a/doc/classes/Signal.xml +++ b/doc/classes/Signal.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="Signal" version="4.0"> <brief_description> + Class representing a signal defined in an object. </brief_description> <description> </description> @@ -15,6 +16,7 @@ <argument index="1" name="signal_name" type="StringName"> </argument> <description> + Creates a new signal named [code]signal_name[/code] in the given object. </description> </method> <method name="connect"> @@ -27,44 +29,51 @@ <argument index="2" name="flags" type="int" default="0"> </argument> <description> + Connects this signal to the specified [Callable], optionally providing binds and connection flags. </description> </method> <method name="disconnect"> - <return type="void"> + <return type="Variant"> </return> <argument index="0" name="callable" type="Callable"> </argument> <description> + Disconnects this signal from the specified [Callable]. </description> </method> <method name="emit" qualifiers="vararg"> <return type="void"> </return> <description> + Emits this signal to all connected objects. </description> </method> <method name="get_connections"> <return type="Array"> </return> <description> + Returns the list of [Callable]s connected to this signal. </description> </method> <method name="get_name"> <return type="StringName"> </return> <description> + Returns the name of this signal. </description> </method> <method name="get_object"> <return type="Object"> </return> <description> + Returns the object emitting this signal. </description> </method> <method name="get_object_id"> <return type="int"> </return> <description> + Returns the ID of the object emitting this signal (see [method Object.get_instance_id]). </description> </method> <method name="is_connected"> @@ -73,6 +82,7 @@ <argument index="0" name="callable" type="Callable"> </argument> <description> + Returns [code]true[/code] if the specified [Callable] is connected to this signal. </description> </method> <method name="is_null"> diff --git a/doc/classes/Sprite.xml b/doc/classes/Sprite.xml index 89cdae1dff..6c21881535 100644 --- a/doc/classes/Sprite.xml +++ b/doc/classes/Sprite.xml @@ -68,10 +68,13 @@ The region of the atlas texture to display. [member region_enabled] must be [code]true[/code]. </member> <member name="shininess" type="float" setter="set_shininess" getter="get_shininess" default="1.0"> + Strength of the specular light effect of this [Sprite]. </member> <member name="specular_color" type="Color" setter="set_specular_color" getter="get_specular_color" default="Color( 1, 1, 1, 1 )"> + The color of the specular light effect. </member> <member name="specular_map" type="Texture2D" setter="set_specular_map" getter="get_specular_map"> + The specular map is used for more control on the shininess effect. </member> <member name="texture" type="Texture2D" setter="set_texture" getter="get_texture"> [Texture2D] object to draw. diff --git a/doc/classes/SpriteBase3D.xml b/doc/classes/SpriteBase3D.xml index aaea4178fb..563a17e8f6 100644 --- a/doc/classes/SpriteBase3D.xml +++ b/doc/classes/SpriteBase3D.xml @@ -21,12 +21,14 @@ <argument index="0" name="flag" type="int" enum="SpriteBase3D.DrawFlags"> </argument> <description> + Returns the value of the specified flag. </description> </method> <method name="get_item_rect" qualifiers="const"> <return type="Rect2"> </return> <description> + Returns the rectangle representing this sprite. </description> </method> <method name="set_draw_flag"> @@ -37,6 +39,7 @@ <argument index="1" name="enabled" type="bool"> </argument> <description> + If [code]true[/code], the specified flag will be enabled. </description> </method> </methods> diff --git a/doc/classes/StreamPeerSSL.xml b/doc/classes/StreamPeerSSL.xml index 738d623d02..69e8f67a5e 100644 --- a/doc/classes/StreamPeerSSL.xml +++ b/doc/classes/StreamPeerSSL.xml @@ -72,11 +72,13 @@ A status representing a [StreamPeerSSL] that is disconnected. </constant> <constant name="STATUS_HANDSHAKING" value="1" enum="Status"> + A status representing a [StreamPeerSSL] during handshaking. </constant> <constant name="STATUS_CONNECTED" value="2" enum="Status"> A status representing a [StreamPeerSSL] that is connected to a host. </constant> <constant name="STATUS_ERROR" value="3" enum="Status"> + A status representing a [StreamPeerSSL] in error state. </constant> <constant name="STATUS_ERROR_HOSTNAME_MISMATCH" value="4" enum="Status"> An error status that shows a mismatch in the SSL certificate domain presented by the host and the domain requested for validation. diff --git a/doc/classes/StreamTexture.xml b/doc/classes/StreamTexture.xml index a2d26d3d14..03afcb5b0d 100644 --- a/doc/classes/StreamTexture.xml +++ b/doc/classes/StreamTexture.xml @@ -15,6 +15,7 @@ <argument index="0" name="path" type="String"> </argument> <description> + Loads the texture from the given path. </description> </method> </methods> diff --git a/doc/classes/StringName.xml b/doc/classes/StringName.xml index f323a4bb6a..5d8ac6fdcc 100644 --- a/doc/classes/StringName.xml +++ b/doc/classes/StringName.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="StringName" version="4.0"> <brief_description> + An optimized string type for unique names. </brief_description> <description> + [StringName]s are immutable strings designed for general-purpose represention of unique names. [StringName] ensures that only one instance of a given name exists (so two [StringName]s with the same value are the same object). Comparing them is much faster than with regular [String]s, because only the pointers are compared, not the whole strings. </description> <tutorials> </tutorials> @@ -13,6 +15,7 @@ <argument index="0" name="from" type="String"> </argument> <description> + Creates a new [StringName] from the given [String]. </description> </method> </methods> diff --git a/doc/classes/TabContainer.xml b/doc/classes/TabContainer.xml index 3c4fd4c41a..f7e94ad236 100644 --- a/doc/classes/TabContainer.xml +++ b/doc/classes/TabContainer.xml @@ -187,36 +187,52 @@ </constants> <theme_items> <theme_item name="decrement" type="Texture2D"> + Icon for the left arrow button that appears when there are too many tabs to fit in the container width. When the button is disabled (i.e. the first tab is visible), it appears semi-transparent. </theme_item> <theme_item name="decrement_highlight" type="Texture2D"> + Icon for the left arrow button that appears when there are too many tabs to fit in the container width. Used when the button is being hovered with the cursor. </theme_item> <theme_item name="font" type="Font"> + The font used to draw tab names. </theme_item> <theme_item name="font_color_bg" type="Color" default="Color( 0.69, 0.69, 0.69, 1 )"> + Font color of inactive tabs. </theme_item> <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )"> + Font color of disabled tabs. </theme_item> <theme_item name="font_color_fg" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> + Font color of the currently selected tab. </theme_item> <theme_item name="hseparation" type="int" default="4"> + Horizontal separation between tabs. </theme_item> <theme_item name="increment" type="Texture2D"> + Icon for the right arrow button that appears when there are too many tabs to fit in the container width. When the button is disabled (i.e. the last tab is visible) it appears semi-transparent. </theme_item> <theme_item name="increment_highlight" type="Texture2D"> + Icon for the right arrow button that appears when there are too many tabs to fit in the container width. Used when the button is being hovered with the cursor. </theme_item> <theme_item name="menu" type="Texture2D"> + The icon for the menu button (see [method set_popup]). </theme_item> <theme_item name="menu_highlight" type="Texture2D"> + The icon for the menu button (see [method set_popup]) when it's being hovered with the cursor. </theme_item> <theme_item name="panel" type="StyleBox"> + The style for the background fill. </theme_item> <theme_item name="side_margin" type="int" default="8"> + The space at the left and right edges of the tab bar. </theme_item> <theme_item name="tab_bg" type="StyleBox"> + The style of inactive tabs. </theme_item> <theme_item name="tab_disabled" type="StyleBox"> + The style of disabled tabs. </theme_item> <theme_item name="tab_fg" type="StyleBox"> + The style of the currently selected tab. </theme_item> </theme_items> </class> diff --git a/doc/classes/Tabs.xml b/doc/classes/Tabs.xml index 8f31b24131..3fc1db9dc6 100644 --- a/doc/classes/Tabs.xml +++ b/doc/classes/Tabs.xml @@ -262,36 +262,51 @@ </constants> <theme_items> <theme_item name="button" type="StyleBox"> + Background of the close button when it's being hovered with the cursor. </theme_item> <theme_item name="button_pressed" type="StyleBox"> + Background of the close button when it's being pressed. </theme_item> <theme_item name="close" type="Texture2D"> + The icon for the close button (see [member tab_close_display_policy]). </theme_item> <theme_item name="decrement" type="Texture2D"> + Icon for the left arrow button that appears when there are too many tabs to fit in the container width. When the button is disabled (i.e. the first tab is visible), it appears semi-transparent. </theme_item> <theme_item name="decrement_highlight" type="Texture2D"> + Icon for the left arrow button that appears when there are too many tabs to fit in the container width. Used when the button is being hovered with the cursor. </theme_item> <theme_item name="font" type="Font"> + The font used to draw tab names. </theme_item> <theme_item name="font_color_bg" type="Color" default="Color( 0.69, 0.69, 0.69, 1 )"> + Font color of inactive tabs. </theme_item> <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )"> + Font color of disabled tabs. </theme_item> <theme_item name="font_color_fg" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> + Font color of the currently selected tab. </theme_item> <theme_item name="hseparation" type="int" default="4"> + The horizontal separation between the tabs. </theme_item> <theme_item name="increment" type="Texture2D"> + Icon for the right arrow button that appears when there are too many tabs to fit in the container width. When the button is disabled (i.e. the last tab is visible) it appears semi-transparent. </theme_item> <theme_item name="increment_highlight" type="Texture2D"> + Icon for the right arrow button that appears when there are too many tabs to fit in the container width. Used when the button is being hovered with the cursor. </theme_item> <theme_item name="panel" type="StyleBox"> </theme_item> <theme_item name="tab_bg" type="StyleBox"> + The style of an inactive tab. </theme_item> <theme_item name="tab_disabled" type="StyleBox"> + The style of a disabled tab </theme_item> <theme_item name="tab_fg" type="StyleBox"> + The style of the currently selected tab. </theme_item> </theme_items> </class> diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index d4eeb574eb..b515b27b31 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -502,6 +502,12 @@ <description> </description> </signal> + <signal name="symbol_validate"> + <argument index="0" name="symbol" type="String"> + </argument> + <description> + </description> + </signal> <signal name="text_changed"> <description> Emitted when the text changes. diff --git a/doc/classes/Transform.xml b/doc/classes/Transform.xml index 72f9c5493a..e4d367c344 100644 --- a/doc/classes/Transform.xml +++ b/doc/classes/Transform.xml @@ -149,7 +149,7 @@ </description> </method> <method name="xform"> - <return type="void"> + <return type="Variant"> </return> <argument index="0" name="v" type="Variant"> </argument> @@ -158,7 +158,7 @@ </description> </method> <method name="xform_inv"> - <return type="void"> + <return type="Variant"> </return> <argument index="0" name="v" type="Variant"> </argument> diff --git a/doc/classes/Transform2D.xml b/doc/classes/Transform2D.xml index 164efd4e5e..af93d4c654 100644 --- a/doc/classes/Transform2D.xml +++ b/doc/classes/Transform2D.xml @@ -151,7 +151,7 @@ </description> </method> <method name="xform"> - <return type="void"> + <return type="Variant"> </return> <argument index="0" name="v" type="Variant"> </argument> @@ -160,7 +160,7 @@ </description> </method> <method name="xform_inv"> - <return type="void"> + <return type="Variant"> </return> <argument index="0" name="v" type="Variant"> </argument> diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml index 5fa24100ae..b01ba3850f 100644 --- a/doc/classes/Tree.xml +++ b/doc/classes/Tree.xml @@ -313,6 +313,7 @@ </signal> <signal name="item_custom_button_pressed"> <description> + Emitted when a custom button is pressed (i.e. in a [constant TreeItem.CELL_MODE_CUSTOM] mode cell). </description> </signal> <signal name="item_double_clicked"> diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml index f498919f9e..84aa3a3686 100644 --- a/doc/classes/TreeItem.xml +++ b/doc/classes/TreeItem.xml @@ -23,8 +23,7 @@ <argument index="4" name="tooltip" type="String" default=""""> </argument> <description> - Adds a button with [Texture2D] [code]button[/code] at column [code]column[/code]. The [code]button_idx[/code] index is used to identify the button when calling other methods. If not specified, the next available index is used, which may be retrieved by calling [method get_button_count] immediately after this method. Optionally, the button can be [code]disabled[/code] and have a [code]tooltip - [/code]. + Adds a button with [Texture2D] [code]button[/code] at column [code]column[/code]. The [code]button_idx[/code] index is used to identify the button when calling other methods. If not specified, the next available index is used, which may be retrieved by calling [method get_button_count] immediately after this method. Optionally, the button can be [code]disabled[/code] and have a [code]tooltip[/code]. </description> </method> <method name="call_recursive" qualifiers="vararg"> diff --git a/doc/classes/VSeparator.xml b/doc/classes/VSeparator.xml index 19e995b9bc..52f31b1da7 100644 --- a/doc/classes/VSeparator.xml +++ b/doc/classes/VSeparator.xml @@ -14,8 +14,10 @@ </constants> <theme_items> <theme_item name="separation" type="int" default="4"> + The width of the area covered by the separator. Effectively works like a minimum width. </theme_item> <theme_item name="separator" type="StyleBox"> + The style for the separator line. Works best with [StyleBoxLine] (remember to enable [member StyleBoxLine.vertical]). </theme_item> </theme_items> </class> diff --git a/doc/classes/VSlider.xml b/doc/classes/VSlider.xml index cbc4ac1a13..3faafdfe80 100644 --- a/doc/classes/VSlider.xml +++ b/doc/classes/VSlider.xml @@ -18,16 +18,22 @@ </constants> <theme_items> <theme_item name="grabber" type="Texture2D"> + The texture for the grabber (the draggable element). </theme_item> <theme_item name="grabber_area" type="StyleBox"> + The background of the area below the grabber. </theme_item> <theme_item name="grabber_disabled" type="Texture2D"> + The texture for the grabber when it's disabled. </theme_item> <theme_item name="grabber_highlight" type="Texture2D"> + The texture for the grabber when it's focused. </theme_item> <theme_item name="slider" type="StyleBox"> + The background for the whole slider. Determines the width of the [code]grabber_area[/code]. </theme_item> <theme_item name="tick" type="Texture2D"> + The texture for the ticks, visible when [member Slider.tick_count] is greater than 0. </theme_item> </theme_items> </class> diff --git a/doc/classes/VSplitContainer.xml b/doc/classes/VSplitContainer.xml index 0e659408d7..18b515e7ce 100644 --- a/doc/classes/VSplitContainer.xml +++ b/doc/classes/VSplitContainer.xml @@ -14,12 +14,15 @@ </constants> <theme_items> <theme_item name="autohide" type="int" default="1"> + Boolean value. If 1 ([code]true[/code]), the grabber will hide automatically when it isn't under the cursor. If 0 ([code]false[/code]), it's always visible. </theme_item> <theme_item name="bg" type="StyleBox"> </theme_item> <theme_item name="grabber" type="Texture2D"> + The icon used for the grabber drawn in the middle area. </theme_item> <theme_item name="separation" type="int" default="12"> + The space between sides of the container. </theme_item> </theme_items> </class> diff --git a/doc/classes/VisualShader.xml b/doc/classes/VisualShader.xml index 0dd8ec0064..40b0f52469 100644 --- a/doc/classes/VisualShader.xml +++ b/doc/classes/VisualShader.xml @@ -22,6 +22,7 @@ <argument index="3" name="id" type="int"> </argument> <description> + Adds the specified node to the shader. </description> </method> <method name="can_connect_nodes" qualifiers="const"> @@ -38,6 +39,7 @@ <argument index="4" name="to_port" type="int"> </argument> <description> + Returns [code]true[/code] if the specified nodes and ports can be connected together. </description> </method> <method name="connect_nodes"> @@ -54,6 +56,7 @@ <argument index="4" name="to_port" type="int"> </argument> <description> + Connects the specified nodes and ports. </description> </method> <method name="connect_nodes_forced"> @@ -70,6 +73,7 @@ <argument index="4" name="to_port" type="int"> </argument> <description> + Connects the specified nodes and ports, even if they can't be connected. Such connection is invalid and will not function properly. </description> </method> <method name="disconnect_nodes"> @@ -86,6 +90,7 @@ <argument index="4" name="to_port" type="int"> </argument> <description> + Connects the specified nodes and ports. </description> </method> <method name="get_node" qualifiers="const"> @@ -96,6 +101,7 @@ <argument index="1" name="id" type="int"> </argument> <description> + Returns the shader node instance with specified [code]type[/code] and [code]id[/code]. </description> </method> <method name="get_node_connections" qualifiers="const"> @@ -104,6 +110,7 @@ <argument index="0" name="type" type="int" enum="VisualShader.Type"> </argument> <description> + Returns the list of connected nodes with the specified type. </description> </method> <method name="get_node_list" qualifiers="const"> @@ -112,6 +119,7 @@ <argument index="0" name="type" type="int" enum="VisualShader.Type"> </argument> <description> + Returns the list of all nodes in the shader with the specified type. </description> </method> <method name="get_node_position" qualifiers="const"> @@ -122,6 +130,7 @@ <argument index="1" name="id" type="int"> </argument> <description> + Returns the position of the specified node within the shader graph. </description> </method> <method name="get_valid_node_id" qualifiers="const"> @@ -146,6 +155,7 @@ <argument index="4" name="to_port" type="int"> </argument> <description> + Returns [code]true[/code] if the specified node and port connection exist. </description> </method> <method name="remove_node"> @@ -156,6 +166,7 @@ <argument index="1" name="id" type="int"> </argument> <description> + Removes the specified node from the shader. </description> </method> <method name="set_mode"> @@ -164,6 +175,7 @@ <argument index="0" name="mode" type="int" enum="Shader.Mode"> </argument> <description> + Sets the mode of this shader. </description> </method> <method name="set_node_position"> @@ -176,22 +188,27 @@ <argument index="2" name="position" type="Vector2"> </argument> <description> + Sets the position of the specified node. </description> </method> </methods> <members> <member name="code" type="String" setter="set_code" getter="get_code" override="true" default=""shader_type spatial;void vertex() {// Output:0}void fragment() {// Output:0}void light() {// Output:0}"" /> <member name="graph_offset" type="Vector2" setter="set_graph_offset" getter="get_graph_offset" default="Vector2( 0, 0 )"> + The offset vector of the whole graph. </member> <member name="version" type="String" setter="set_version" getter="get_version" default=""""> </member> </members> <constants> <constant name="TYPE_VERTEX" value="0" enum="Type"> + A vertex shader, operating on vertices. </constant> <constant name="TYPE_FRAGMENT" value="1" enum="Type"> + A fragment shader, operating on fragments (pixels). </constant> <constant name="TYPE_LIGHT" value="2" enum="Type"> + A shader for light calculations. </constant> <constant name="TYPE_MAX" value="3" enum="Type"> Represents the size of the [enum Type] enum. diff --git a/doc/classes/VisualShaderNode.xml b/doc/classes/VisualShaderNode.xml index 72ce743656..28d13a7d32 100644 --- a/doc/classes/VisualShaderNode.xml +++ b/doc/classes/VisualShaderNode.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualShaderNode" inherits="Resource" version="4.0"> <brief_description> + Base class for nodes in a visual shader graph. </brief_description> <description> </description> diff --git a/doc/classes/VisualShaderNodeIf.xml b/doc/classes/VisualShaderNodeIf.xml index 1ebd945d42..ad0b21a370 100644 --- a/doc/classes/VisualShaderNodeIf.xml +++ b/doc/classes/VisualShaderNodeIf.xml @@ -4,7 +4,7 @@ Compares two floating-point numbers in order to return a required vector within the visual shader graph. </brief_description> <description> - First two ports are scalar floatin-point numbers to compare, third is tolerance comparsion amount and last three ports represents a vectors returned if [code]a == b[/code], [code]a > b[/code] and [code]a < b[/code] respectivly. + First two ports are scalar floatin-point numbers to compare, third is tolerance comparison amount and last three ports represents a vectors returned if [code]a == b[/code], [code]a > b[/code] and [code]a < b[/code] respectively. </description> <tutorials> </tutorials> diff --git a/doc/classes/WindowDialog.xml b/doc/classes/WindowDialog.xml index 16b8085df3..8b6bf00508 100644 --- a/doc/classes/WindowDialog.xml +++ b/doc/classes/WindowDialog.xml @@ -29,22 +29,31 @@ </constants> <theme_items> <theme_item name="close" type="Texture2D"> + The icon for the close button. </theme_item> <theme_item name="close_h_ofs" type="int" default="18"> + The horizontal offset of the close button. </theme_item> <theme_item name="close_highlight" type="Texture2D"> + The icon used for the close button when it's hovered with the mouse cursor. </theme_item> <theme_item name="close_v_ofs" type="int" default="18"> + The vertical offset of the close button. </theme_item> <theme_item name="panel" type="StyleBox"> + The style for both the content background of the [WindowDialog] and the title bar. </theme_item> <theme_item name="scaleborder_size" type="int" default="4"> + The thickness of the border that can be dragged when scaling the window (if [member resizable] is enabled). </theme_item> <theme_item name="title_color" type="Color" default="Color( 0, 0, 0, 1 )"> + The color of the title text. </theme_item> <theme_item name="title_font" type="Font"> + The font used to draw the title. </theme_item> <theme_item name="title_height" type="int" default="20"> + The vertical offset of the title text. </theme_item> </theme_items> </class> diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h index 4df28e3ea4..4dc634aefa 100644 --- a/drivers/dummy/rasterizer_dummy.h +++ b/drivers/dummy/rasterizer_dummy.h @@ -167,7 +167,7 @@ public: Vector<uint8_t> index_array; int index_count; AABB aabb; - Vector<Vector<uint8_t> > blend_shapes; + Vector<Vector<uint8_t>> blend_shapes; Vector<AABB> bone_aabbs; }; @@ -181,8 +181,8 @@ public: mutable RID_PtrOwner<DummyMesh> mesh_owner; virtual RID texture_2d_create(const Ref<Image> &p_image) { return RID(); } - virtual RID texture_2d_layered_create(const Vector<Ref<Image> > &p_layers, VS::TextureLayeredType p_layered_type) { return RID(); } - virtual RID texture_3d_create(const Vector<Ref<Image> > &p_slices) { return RID(); } + virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, VS::TextureLayeredType p_layered_type) { return RID(); } + virtual RID texture_3d_create(const Vector<Ref<Image>> &p_slices) { return RID(); } virtual RID texture_proxy_create(RID p_base) { return RID(); } virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) {} diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index 55b1c7e560..0f5452effc 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -2270,7 +2270,7 @@ static Vector<uint8_t> _unpack_half_floats(const Vector<uint8_t> &array, uint32_ return ret; } -void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t> > &p_blend_shapes, const Vector<AABB> &p_bone_aabbs) { +void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t>> &p_blend_shapes, const Vector<AABB> &p_bone_aabbs) { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND(!mesh); @@ -2737,10 +2737,10 @@ AABB RasterizerStorageGLES2::mesh_surface_get_aabb(RID p_mesh, int p_surface) co return mesh->surfaces[p_surface]->aabb; } -Vector<Vector<uint8_t> > RasterizerStorageGLES2::mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const { +Vector<Vector<uint8_t>> RasterizerStorageGLES2::mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const { const Mesh *mesh = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!mesh, Vector<Vector<uint8_t> >()); - ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), Vector<Vector<uint8_t> >()); + ERR_FAIL_COND_V(!mesh, Vector<Vector<uint8_t>>()); + ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), Vector<Vector<uint8_t>>()); #ifndef TOOLS_ENABLED ERR_PRINT("OpenGL ES 2.0 does not allow retrieving mesh array data"); #endif diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h index 6fbfe57778..86965730e0 100644 --- a/drivers/gles2/rasterizer_storage_gles2.h +++ b/drivers/gles2/rasterizer_storage_gles2.h @@ -275,7 +275,7 @@ public: RenderTarget *render_target; - Vector<Ref<Image> > images; + Vector<Ref<Image>> images; bool redraw_if_visible; @@ -541,7 +541,7 @@ public: Map<StringName, Variant> params; SelfList<Material> list; SelfList<Material> dirty_list; - Vector<Pair<StringName, RID> > textures; + Vector<Pair<StringName, RID>> textures; float line_width; int render_priority; @@ -650,7 +650,7 @@ public: Vector<uint8_t> data; Vector<uint8_t> index_data; - Vector<Vector<uint8_t> > blend_shape_data; + Vector<Vector<uint8_t>> blend_shape_data; int total_data_size; @@ -702,7 +702,7 @@ public: virtual RID mesh_create(); - virtual void mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t> > &p_blend_shapes = Vector<Vector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>()); + virtual void mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t>> &p_blend_shapes = Vector<Vector<uint8_t>>(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>()); virtual void mesh_set_blend_shape_count(RID p_mesh, int p_amount); virtual int mesh_get_blend_shape_count(RID p_mesh) const; @@ -725,7 +725,7 @@ public: virtual VS::PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const; virtual AABB mesh_surface_get_aabb(RID p_mesh, int p_surface) const; - virtual Vector<Vector<uint8_t> > mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const; + virtual Vector<Vector<uint8_t>> mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const; virtual Vector<AABB> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const; virtual void mesh_remove_surface(RID p_mesh, int p_surface); diff --git a/drivers/gles2/shader_compiler_gles2.h b/drivers/gles2/shader_compiler_gles2.h index e39ef5e7bd..dd10a27c0d 100644 --- a/drivers/gles2/shader_compiler_gles2.h +++ b/drivers/gles2/shader_compiler_gles2.h @@ -41,7 +41,7 @@ class ShaderCompilerGLES2 { public: struct IdentifierActions { - Map<StringName, Pair<int *, int> > render_mode_values; + Map<StringName, Pair<int *, int>> render_mode_values; Map<StringName, bool *> render_mode_flags; Map<StringName, bool *> usage_flag_pointers; Map<StringName, bool *> write_flag_pointers; diff --git a/drivers/gles2/shader_gles2.h b/drivers/gles2/shader_gles2.h index f2953c9ae8..d5e8159479 100644 --- a/drivers/gles2/shader_gles2.h +++ b/drivers/gles2/shader_gles2.h @@ -179,7 +179,7 @@ private: int max_image_units; - Map<StringName, Pair<ShaderLanguage::DataType, Vector<ShaderLanguage::ConstantNode::Value> > > uniform_values; + Map<StringName, Pair<ShaderLanguage::DataType, Vector<ShaderLanguage::ConstantNode::Value>>> uniform_values; protected: _FORCE_INLINE_ int _get_uniform(int p_which) const; diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 361982b28d..76541c3cd5 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -57,7 +57,7 @@ void RenderingDeviceVulkan::_free_dependencies(RID p_id) { //direct dependencies must be freed - Map<RID, Set<RID> >::Element *E = dependency_map.find(p_id); + Map<RID, Set<RID>>::Element *E = dependency_map.find(p_id); if (E) { while (E->get().size()) { @@ -72,7 +72,7 @@ void RenderingDeviceVulkan::_free_dependencies(RID p_id) { if (E) { for (Set<RID>::Element *F = E->get().front(); F; F = F->next()) { - Map<RID, Set<RID> >::Element *G = dependency_map.find(F->get()); + Map<RID, Set<RID>>::Element *G = dependency_map.find(F->get()); ERR_CONTINUE(!G); ERR_CONTINUE(!G->get().has(p_id)); G->get().erase(p_id); @@ -1555,7 +1555,7 @@ void RenderingDeviceVulkan::_buffer_memory_barrier(VkBuffer buffer, uint64_t p_f /**** TEXTURE ****/ /*****************/ -RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<Vector<uint8_t> > &p_data) { +RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<Vector<uint8_t>> &p_data) { _THREAD_SAFE_METHOD_ @@ -3568,8 +3568,8 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages) { //descriptor layouts - Vector<Vector<VkDescriptorSetLayoutBinding> > set_bindings; - Vector<Vector<UniformInfo> > uniform_info; + Vector<Vector<VkDescriptorSetLayoutBinding>> set_bindings; + Vector<Vector<UniformInfo>> uniform_info; Shader::PushConstant push_constant; push_constant.push_constant_size = 0; push_constant.push_constants_vk_stage = 0; @@ -4223,9 +4223,9 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, DescriptorPoolKey pool_key; //to keep them alive until update call - List<Vector<VkDescriptorBufferInfo> > buffer_infos; - List<Vector<VkBufferView> > buffer_views; - List<Vector<VkDescriptorImageInfo> > image_infos; + List<Vector<VkDescriptorBufferInfo>> buffer_infos; + List<Vector<VkBufferView>> buffer_views; + List<Vector<VkDescriptorImageInfo>> image_infos; //used for verification to make sure a uniform set does not use a framebuffer bound texture Vector<RID> attachable_textures; Vector<Texture *> mutable_sampled_textures; diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 30c10e922e..4a224f0ceb 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -98,8 +98,8 @@ class RenderingDeviceVulkan : public RenderingDevice { VkDevice device; - Map<RID, Set<RID> > dependency_map; //IDs to IDs that depend on it - Map<RID, Set<RID> > reverse_dependency_map; //same as above, but in reverse + Map<RID, Set<RID>> dependency_map; //IDs to IDs that depend on it + Map<RID, Set<RID>> reverse_dependency_map; //same as above, but in reverse void _add_dependency(RID p_id, RID p_depends_on); void _free_dependencies(RID p_id); @@ -602,7 +602,7 @@ class RenderingDeviceVulkan : public RenderingDevice { uint32_t usage; }; - Map<DescriptorPoolKey, Set<DescriptorPool *> > descriptor_pools; + Map<DescriptorPoolKey, Set<DescriptorPool *>> descriptor_pools; uint32_t max_descriptors_per_pool; DescriptorPool *_descriptor_pool_allocate(const DescriptorPoolKey &p_key); @@ -968,7 +968,7 @@ class RenderingDeviceVulkan : public RenderingDevice { void _free_rids(T &p_owner, const char *p_type); public: - virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<Vector<uint8_t> > &p_data = Vector<Vector<uint8_t> >()); + virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<Vector<uint8_t>> &p_data = Vector<Vector<uint8_t>>()); virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture); virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D); diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index e0839a9f27..6dcc9dd8ae 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -1076,7 +1076,7 @@ void AnimationBezierTrackEdit::duplicate_selection() { undo_redo->create_action(TTR("Anim Duplicate Keys")); - List<Pair<int, float> > new_selection_values; + List<Pair<int, float>> new_selection_values; for (Set<int>::Element *E = selection.back(); E; E = E->prev()) { @@ -1103,7 +1103,7 @@ void AnimationBezierTrackEdit::duplicate_selection() { //reselect duplicated selection.clear(); - for (List<Pair<int, float> >::Element *E = new_selection_values.front(); E; E = E->next()) { + for (List<Pair<int, float>>::Element *E = new_selection_values.front(); E; E = E->next()) { int track = E->get().first; float time = E->get().second; diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 095dbd6849..fb427afe24 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -752,7 +752,7 @@ public: if (animation != p_anim) return; - for (Map<int, List<float> >::Element *E = key_ofs_map.front(); E; E = E->next()) { + for (Map<int, List<float>>::Element *E = key_ofs_map.front(); E; E = E->next()) { for (List<float>::Element *F = E->value().front(); F; F = F->next()) { @@ -777,7 +777,7 @@ public: bool update_obj = false; bool change_notify_deserved = false; - for (Map<int, List<float> >::Element *E = key_ofs_map.front(); E; E = E->next()) { + for (Map<int, List<float>>::Element *E = key_ofs_map.front(); E; E = E->next()) { int track = E->key(); for (List<float>::Element *F = E->value().front(); F; F = F->next()) { @@ -1060,7 +1060,7 @@ public: bool _get(const StringName &p_name, Variant &r_ret) const { - for (Map<int, List<float> >::Element *E = key_ofs_map.front(); E; E = E->next()) { + for (Map<int, List<float>>::Element *E = key_ofs_map.front(); E; E = E->next()) { int track = E->key(); for (List<float>::Element *F = E->value().front(); F; F = F->next()) { @@ -1208,7 +1208,7 @@ public: bool show_time = true; bool same_track_type = true; bool same_key_type = true; - for (Map<int, List<float> >::Element *E = key_ofs_map.front(); E; E = E->next()) { + for (Map<int, List<float>>::Element *E = key_ofs_map.front(); E; E = E->next()) { int track = E->key(); ERR_FAIL_INDEX(track, animation->get_track_count()); @@ -1362,7 +1362,7 @@ public: Ref<Animation> animation; - Map<int, List<float> > key_ofs_map; + Map<int, List<float>> key_ofs_map; Map<int, NodePath> base_map; PropertyInfo hint; @@ -4892,7 +4892,7 @@ void AnimationTrackEditor::_update_key_edit() { multi_key_edit = memnew(AnimationMultiTrackKeyEdit); multi_key_edit->animation = animation; - Map<int, List<float> > key_ofs_map; + Map<int, List<float>> key_ofs_map; Map<int, NodePath> base_map; int first_track = -1; for (Map<SelectedKey, KeyInfo>::Element *E = selection.front(); E; E = E->next()) { @@ -5186,7 +5186,7 @@ void AnimationTrackEditor::_anim_duplicate_keys(bool transpose) { undo_redo->create_action(TTR("Anim Duplicate Keys")); - List<Pair<int, float> > new_selection_values; + List<Pair<int, float>> new_selection_values; for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) { @@ -5224,7 +5224,7 @@ void AnimationTrackEditor::_anim_duplicate_keys(bool transpose) { //reselect duplicated Map<SelectedKey, KeyInfo> new_selection; - for (List<Pair<int, float> >::Element *E = new_selection_values.front(); E; E = E->next()) { + for (List<Pair<int, float>>::Element *E = new_selection_values.front(); E; E = E->next()) { int track = E->get().first; float time = E->get().second; diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index 26f9c15f6c..8de56a153e 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -430,7 +430,7 @@ class AnimationTrackEditor : public VBoxContainer { Rect2 box_select_rect; void _scroll_input(const Ref<InputEvent> &p_event); - Vector<Ref<AnimationTrackEditPlugin> > track_edit_plugins; + Vector<Ref<AnimationTrackEditPlugin>> track_edit_plugins; void _cancel_bezier_edit(); void _bezier_edit(int p_for_track); diff --git a/editor/collada/collada.cpp b/editor/collada/collada.cpp index 231173e459..8ef9d17083 100644 --- a/editor/collada/collada.cpp +++ b/editor/collada/collada.cpp @@ -1773,12 +1773,12 @@ void Collada::_parse_animation(XMLParser &parser) { return; } - Map<String, Vector<float> > float_sources; - Map<String, Vector<String> > string_sources; + Map<String, Vector<float>> float_sources; + Map<String, Vector<String>> string_sources; Map<String, int> source_strides; - Map<String, Map<String, String> > samplers; - Map<String, Vector<String> > source_param_names; - Map<String, Vector<String> > source_param_types; + Map<String, Map<String, String>> samplers; + Map<String, Vector<String>> source_param_names; + Map<String, Vector<String>> source_param_types; String id = ""; if (parser.has_attribute("id")) @@ -2194,7 +2194,11 @@ void Collada::_merge_skeletons(VisualScene *p_vscene, Node *p_node) { ERR_CONTINUE(!state.scene_map.has(nodeid)); //weird, it should have it... - NodeJoint *nj = SAFE_CAST<NodeJoint *>(state.scene_map[nodeid]); +#ifdef NO_SAFE_CAST + NodeJoint *nj = static_cast<NodeJoint *>(state.scene_map[nodeid]); +#else + NodeJoint *nj = dynamic_cast<NodeJoint *>(state.scene_map[nodeid]); +#endif ERR_CONTINUE(!nj); //broken collada ERR_CONTINUE(!nj->owner); //weird, node should have a skeleton owner @@ -2366,7 +2370,11 @@ bool Collada::_move_geometry_to_skeletons(VisualScene *p_vscene, Node *p_node, L String nodeid = ng->skeletons[0]; ERR_FAIL_COND_V(!state.scene_map.has(nodeid), false); //weird, it should have it... - NodeJoint *nj = SAFE_CAST<NodeJoint *>(state.scene_map[nodeid]); +#ifdef NO_SAFE_CAST + NodeJoint *nj = static_cast<NodeJoint *>(state.scene_map[nodeid]); +#else + NodeJoint *nj = dynamic_cast<NodeJoint *>(state.scene_map[nodeid]); +#endif ERR_FAIL_COND_V(!nj, false); ERR_FAIL_COND_V(!nj->owner, false); //weird, node should have a skeleton owner diff --git a/editor/collada/collada.h b/editor/collada/collada.h index 10ed42260b..4707d7d779 100644 --- a/editor/collada/collada.h +++ b/editor/collada/collada.h @@ -570,8 +570,8 @@ public: Vector<AnimationClip> animation_clips; Vector<AnimationTrack> animation_tracks; - Map<String, Vector<int> > referenced_tracks; - Map<String, Vector<int> > by_id_tracks; + Map<String, Vector<int>> referenced_tracks; + Map<String, Vector<int>> by_id_tracks; float animation_length; diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index eea92fb7ed..23df649851 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -977,7 +977,7 @@ void ConnectionsDock::update_tree() { String descr; bool found = false; - Map<StringName, Map<StringName, String> >::Element *G = descr_cache.find(base); + Map<StringName, Map<StringName, String>>::Element *G = descr_cache.find(base); if (G) { Map<StringName, String>::Element *F = G->get().find(signal_name); if (F) { diff --git a/editor/connections_dialog.h b/editor/connections_dialog.h index 988a8a1271..8f29a4f720 100644 --- a/editor/connections_dialog.h +++ b/editor/connections_dialog.h @@ -173,7 +173,7 @@ class ConnectionsDock : public VBoxContainer { PopupMenu *slot_menu; UndoRedo *undo_redo; - Map<StringName, Map<StringName, String> > descr_cache; + Map<StringName, Map<StringName, String>> descr_cache; void _make_or_edit_connection(); void _connect(ConnectDialog::ConnectionData cToMake); diff --git a/editor/debugger/editor_debugger_tree.cpp b/editor/debugger/editor_debugger_tree.cpp index 441f6082c3..019a5d0fc3 100644 --- a/editor/debugger/editor_debugger_tree.cpp +++ b/editor/debugger/editor_debugger_tree.cpp @@ -132,7 +132,7 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int const String filter = EditorNode::get_singleton()->get_scene_tree_dock()->get_filter(); // Nodes are in a flatten list, depth first. Use a stack of parents, avoid recursion. - List<Pair<TreeItem *, int> > parents; + List<Pair<TreeItem *, int>> parents; for (int i = 0; i < p_tree->nodes.size(); i++) { TreeItem *parent = NULL; if (parents.size()) { // Find last parent. diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp index 2f3ad210b2..ca4979563d 100644 --- a/editor/debugger/editor_profiler.cpp +++ b/editor/debugger/editor_profiler.cpp @@ -611,8 +611,8 @@ bool EditorProfiler::is_profiling() { return activate->is_pressed(); } -Vector<Vector<String> > EditorProfiler::get_data_as_csv() const { - Vector<Vector<String> > res; +Vector<Vector<String>> EditorProfiler::get_data_as_csv() const { + Vector<Vector<String>> res; if (frame_metrics.empty()) { return res; diff --git a/editor/debugger/editor_profiler.h b/editor/debugger/editor_profiler.h index 0a442ddd5c..4afd2c8302 100644 --- a/editor/debugger/editor_profiler.h +++ b/editor/debugger/editor_profiler.h @@ -169,7 +169,7 @@ public: void clear(); - Vector<Vector<String> > get_data_as_csv() const; + Vector<Vector<String>> get_data_as_csv() const; EditorProfiler(); }; diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp index 52aa418922..48425062d1 100644 --- a/editor/debugger/editor_visual_profiler.cpp +++ b/editor/debugger/editor_visual_profiler.cpp @@ -678,8 +678,8 @@ bool EditorVisualProfiler::is_profiling() { return activate->is_pressed(); } -Vector<Vector<String> > EditorVisualProfiler::get_data_as_csv() const { - Vector<Vector<String> > res; +Vector<Vector<String>> EditorVisualProfiler::get_data_as_csv() const { + Vector<Vector<String>> res; #if 0 if (frame_metrics.empty()) { return res; diff --git a/editor/debugger/editor_visual_profiler.h b/editor/debugger/editor_visual_profiler.h index 5194c08b96..d3a758557c 100644 --- a/editor/debugger/editor_visual_profiler.h +++ b/editor/debugger/editor_visual_profiler.h @@ -146,7 +146,7 @@ public: void clear(); - Vector<Vector<String> > get_data_as_csv() const; + Vector<Vector<String>> get_data_as_csv() const; EditorVisualProfiler(); }; diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index 920f4d858a..d7c0c3d2bf 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -165,7 +165,7 @@ void ScriptEditorDebugger::_file_selected(const String &p_file) { file->store_csv_line(line); // values - List<Vector<float> >::Element *E = perf_history.back(); + List<Vector<float>>::Element *E = perf_history.back(); while (E) { Vector<float> &perf_data = E->get(); @@ -178,7 +178,7 @@ void ScriptEditorDebugger::_file_selected(const String &p_file) { } file->store_string("\n"); - Vector<Vector<String> > profiler_data = profiler->get_data_as_csv(); + Vector<Vector<String>> profiler_data = profiler->get_data_as_csv(); for (int i = 0; i < profiler_data.size(); i++) { file->store_csv_line(profiler_data[i]); } @@ -728,7 +728,7 @@ void ScriptEditorDebugger::_performance_draw() { float spacing = point_sep / float(cols); float from = r.size.width; - List<Vector<float> >::Element *E = perf_history.front(); + List<Vector<float>>::Element *E = perf_history.front(); float prev = -1; while (from >= 0 && E) { @@ -1425,7 +1425,7 @@ void ScriptEditorDebugger::_item_menu_id_pressed(int p_option) { void ScriptEditorDebugger::_tab_changed(int p_tab) { if (tabs->get_tab_title(p_tab) == TTR("Video RAM")) { - // "Video RAM" tab was clicked, refresh the data it's dislaying when entering the tab. + // "Video RAM" tab was clicked, refresh the data it's displaying when entering the tab. _video_mem_request(); } } diff --git a/editor/debugger/script_editor_debugger.h b/editor/debugger/script_editor_debugger.h index e7ce917543..7944d7cb99 100644 --- a/editor/debugger/script_editor_debugger.h +++ b/editor/debugger/script_editor_debugger.h @@ -109,7 +109,7 @@ private: // Each debugger should have it's tree in the future I guess. const Tree *editor_remote_tree = NULL; - List<Vector<float> > perf_history; + List<Vector<float>> perf_history; Vector<float> perf_max; Vector<TreeItem *> perf_items; diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index 0c95a64d06..5a0accd45c 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -63,7 +63,7 @@ void DependencyEditor::_load_pressed(Object *p_item, int p_cell, int p_button) { search->popup_centered_ratio(0.65); // So it doesn't completely cover the dialog below it. } -void DependencyEditor::_fix_and_find(EditorFileSystemDirectory *efsd, Map<String, Map<String, String> > &candidates) { +void DependencyEditor::_fix_and_find(EditorFileSystemDirectory *efsd, Map<String, Map<String, String>> &candidates) { for (int i = 0; i < efsd->get_subdir_count(); i++) { _fix_and_find(efsd->get_subdir(i), candidates); @@ -124,7 +124,7 @@ void DependencyEditor::_fix_all() { if (!EditorFileSystem::get_singleton()->get_filesystem()) return; - Map<String, Map<String, String> > candidates; + Map<String, Map<String, String>> candidates; for (List<String>::Element *E = missing.front(); E; E = E->next()) { @@ -140,7 +140,7 @@ void DependencyEditor::_fix_all() { Map<String, String> remaps; - for (Map<String, Map<String, String> >::Element *E = candidates.front(); E; E = E->next()) { + for (Map<String, Map<String, String>>::Element *E = candidates.front(); E; E = E->next()) { for (Map<String, String>::Element *F = E->get().front(); F; F = F->next()) { diff --git a/editor/dependency_editor.h b/editor/dependency_editor.h index be8d34f406..ee74072731 100644 --- a/editor/dependency_editor.h +++ b/editor/dependency_editor.h @@ -52,7 +52,7 @@ class DependencyEditor : public AcceptDialog { String editing; List<String> missing; - void _fix_and_find(EditorFileSystemDirectory *efsd, Map<String, Map<String, String> > &candidates); + void _fix_and_find(EditorFileSystemDirectory *efsd, Map<String, Map<String, String>> &candidates); void _searched(const String &p_path); void _load_pressed(Object *p_item, int p_cell, int p_button); diff --git a/editor/doc/doc_data.cpp b/editor/doc/doc_data.cpp index 38ff9cd5fc..66134b4428 100644 --- a/editor/doc/doc_data.cpp +++ b/editor/doc/doc_data.cpp @@ -687,10 +687,10 @@ void DocData::generate(bool p_basic_types) { c.methods.push_back(md); } - List<Pair<String, Variant> > cinfo; + List<Pair<String, Variant>> cinfo; lang->get_public_constants(&cinfo); - for (List<Pair<String, Variant> >::Element *E = cinfo.front(); E; E = E->next()) { + for (List<Pair<String, Variant>>::Element *E = cinfo.front(); E; E = E->next()) { ConstantDoc cd; cd.name = E->get().first; diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp index 73c70f422d..e26d44025f 100644 --- a/editor/editor_asset_installer.cpp +++ b/editor/editor_asset_installer.cpp @@ -110,7 +110,7 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) { ret = unzGoToNextFile(pkg); } - Map<String, Ref<Texture2D> > extension_guess; + Map<String, Ref<Texture2D>> extension_guess; { extension_guess["png"] = get_icon("ImageTexture", "EditorIcons"); extension_guess["jpg"] = get_icon("ImageTexture", "EditorIcons"); diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 192e7d286f..1c19327da7 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -521,7 +521,7 @@ Object *EditorData::instance_custom_type(const String &p_type, const String &p_i void EditorData::remove_custom_type(const String &p_type) { - for (Map<String, Vector<CustomType> >::Element *E = custom_types.front(); E; E = E->next()) { + for (Map<String, Vector<CustomType>>::Element *E = custom_types.front(); E; E = E->next()) { for (int i = 0; i < E->get().size(); i++) { if (E->get()[i].name == p_type) { diff --git a/editor/editor_data.h b/editor/editor_data.h index 8a6f2f63f6..5095ea8479 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -135,7 +135,7 @@ private: String name; Variant value; }; - Map<String, Vector<CustomType> > custom_types; + Map<String, Vector<CustomType>> custom_types; List<PropertyData> clipboard; UndoRedo undo_redo; @@ -181,7 +181,7 @@ public: void add_custom_type(const String &p_type, const String &p_inherits, const Ref<Script> &p_script, const Ref<Texture2D> &p_icon); Object *instance_custom_type(const String &p_type, const String &p_inherits); void remove_custom_type(const String &p_type); - const Map<String, Vector<CustomType> > &get_custom_types() const { return custom_types; } + const Map<String, Vector<CustomType>> &get_custom_types() const { return custom_types; } int add_edited_scene(int p_at_pos); void move_edited_scene_index(int p_idx, int p_to_idx); diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index 4941f295d7..5883b5eb1e 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -664,7 +664,7 @@ EditorExportPlatform::FeatureContainers EditorExportPlatform::get_feature_contai EditorExportPlatform::ExportNotifier::ExportNotifier(EditorExportPlatform &p_platform, const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { FeatureContainers features = p_platform.get_feature_containers(p_preset); - Vector<Ref<EditorExportPlugin> > export_plugins = EditorExport::get_singleton()->get_export_plugins(); + Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins(); //initial export plugin callback for (int i = 0; i < export_plugins.size(); i++) { if (export_plugins[i]->get_script_instance()) { //script based @@ -676,7 +676,7 @@ EditorExportPlatform::ExportNotifier::ExportNotifier(EditorExportPlatform &p_pla } 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++) { if (export_plugins[i]->get_script_instance()) { export_plugins.write[i]->_export_end_script(); @@ -712,7 +712,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & _edit_filter_list(paths, p_preset->get_include_filter(), false); _edit_filter_list(paths, p_preset->get_exclude_filter(), true); - 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++) { export_plugins.write[i]->set_export_preset(p_preset); @@ -1284,7 +1284,7 @@ void EditorExport::remove_export_plugin(const Ref<EditorExportPlugin> &p_plugin) export_plugins.erase(p_plugin); } -Vector<Ref<EditorExportPlugin> > EditorExport::get_export_plugins() { +Vector<Ref<EditorExportPlugin>> EditorExport::get_export_plugins() { return export_plugins; } diff --git a/editor/editor_export.h b/editor/editor_export.h index 139d672cb8..81790eb0a4 100644 --- a/editor/editor_export.h +++ b/editor/editor_export.h @@ -347,9 +347,9 @@ public: class EditorExport : public Node { GDCLASS(EditorExport, Node); - Vector<Ref<EditorExportPlatform> > export_platforms; - Vector<Ref<EditorExportPreset> > export_presets; - Vector<Ref<EditorExportPlugin> > export_plugins; + Vector<Ref<EditorExportPlatform>> export_platforms; + Vector<Ref<EditorExportPreset>> export_presets; + Vector<Ref<EditorExportPlugin>> export_plugins; Timer *save_timer; bool block_save; @@ -379,7 +379,7 @@ public: void add_export_plugin(const Ref<EditorExportPlugin> &p_plugin); void remove_export_plugin(const Ref<EditorExportPlugin> &p_plugin); - Vector<Ref<EditorExportPlugin> > get_export_plugins(); + Vector<Ref<EditorExportPlugin>> get_export_plugins(); void load_config(); diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp index 959507535b..4b0bbdcec2 100644 --- a/editor/editor_feature_profile.cpp +++ b/editor/editor_feature_profile.cpp @@ -153,7 +153,7 @@ Error EditorFeatureProfile::save_to_file(const String &p_path) { Array dis_props; - for (Map<StringName, Set<StringName> >::Element *E = disabled_properties.front(); E; E = E->next()) { + for (Map<StringName, Set<StringName>>::Element *E = disabled_properties.front(); E; E = E->next()) { for (Set<StringName>::Element *F = E->get().front(); F; F = F->next()) { dis_props.push_back(String(E->key()) + ":" + String(F->get())); } diff --git a/editor/editor_feature_profile.h b/editor/editor_feature_profile.h index a5ab73da60..5ae2398027 100644 --- a/editor/editor_feature_profile.h +++ b/editor/editor_feature_profile.h @@ -58,7 +58,7 @@ public: private: Set<StringName> disabled_classes; Set<StringName> disabled_editors; - Map<StringName, Set<StringName> > disabled_properties; + Map<StringName, Set<StringName>> disabled_properties; bool features_disabled[FEATURE_MAX]; static const char *feature_names[FEATURE_MAX]; diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index b5ec08ef60..ad34b59c5c 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -1558,7 +1558,7 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector String importer_name; - Map<String, Map<StringName, Variant> > source_file_options; + Map<String, Map<StringName, Variant>> source_file_options; Map<String, String> base_paths; for (int i = 0; i < p_files.size(); i++) { @@ -1610,7 +1610,7 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector Error err = importer->import_group_file(p_group_file, source_file_options, base_paths); //all went well, overwrite config files with proper remaps and md5s - for (Map<String, Map<StringName, Variant> >::Element *E = source_file_options.front(); E; E = E->next()) { + for (Map<String, Map<StringName, Variant>>::Element *E = source_file_options.front(); E; E = E->next()) { const String &file = E->key(); String base_path = ResourceFormatImporter::get_singleton()->get_import_base_path(file); @@ -1921,7 +1921,7 @@ void EditorFileSystem::_reimport_file(const String &p_file) { EditorResourcePreview::get_singleton()->check_for_invalidation(p_file); } -void EditorFileSystem::_find_group_files(EditorFileSystemDirectory *efd, Map<String, Vector<String> > &group_files, Set<String> &groups_to_reimport) { +void EditorFileSystem::_find_group_files(EditorFileSystemDirectory *efd, Map<String, Vector<String>> &group_files, Set<String> &groups_to_reimport) { int fc = efd->files.size(); const EditorFileSystemDirectory::FileInfo *const *files = efd->files.ptr(); @@ -1998,9 +1998,9 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) { //reimport groups if (groups_to_reimport.size()) { - Map<String, Vector<String> > group_files; + Map<String, Vector<String>> group_files; _find_group_files(filesystem, group_files, groups_to_reimport); - for (Map<String, Vector<String> >::Element *E = group_files.front(); E; E = E->next()) { + for (Map<String, Vector<String>>::Element *E = group_files.front(); E; E = E->next()) { Error err = _reimport_group(E->key(), E->get()); if (err == OK) { diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index 381acc0fe2..9789dacdc1 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -240,7 +240,7 @@ class EditorFileSystem : public Node { bool using_fat32_or_exfat; // Workaround for projects in FAT32 or exFAT filesystem (pendrives, most of the time) - void _find_group_files(EditorFileSystemDirectory *efd, Map<String, Vector<String> > &group_files, Set<String> &groups_to_reimport); + void _find_group_files(EditorFileSystemDirectory *efd, Map<String, Vector<String>> &group_files, Set<String> &groups_to_reimport); void _move_group_files(EditorFileSystemDirectory *efd, const String &p_group_file, const String &p_new_location); diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index b26fa77e16..4526a3a52c 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -812,7 +812,7 @@ void EditorHelp::_update_doc() { // Constants and enums if (cd.constants.size()) { - Map<String, Vector<DocData::ConstantDoc> > enums; + Map<String, Vector<DocData::ConstantDoc>> enums; Vector<DocData::ConstantDoc> constants; for (int i = 0; i < cd.constants.size(); i++) { @@ -842,7 +842,7 @@ void EditorHelp::_update_doc() { class_desc->add_newline(); - for (Map<String, Vector<DocData::ConstantDoc> >::Element *E = enums.front(); E; E = E->next()) { + for (Map<String, Vector<DocData::ConstantDoc>>::Element *E = enums.front(); E; E = E->next()) { enum_line[E->key()] = class_desc->get_line_count() - 2; @@ -1188,7 +1188,7 @@ void EditorHelp::_help_callback(const String &p_topic) { if (constant_line.has(name)) line = constant_line[name]; else { - Map<String, Map<String, int> >::Element *iter = enum_values_line.front(); + Map<String, Map<String, int>>::Element *iter = enum_values_line.front(); while (true) { if (iter->value().has(name)) { line = iter->value()[name]; @@ -1489,8 +1489,8 @@ void EditorHelp::go_to_class(const String &p_class, int p_scroll) { _goto_desc(p_class, p_scroll); } -Vector<Pair<String, int> > EditorHelp::get_sections() { - Vector<Pair<String, int> > sections; +Vector<Pair<String, int>> EditorHelp::get_sections() { + Vector<Pair<String, int>> sections; for (int i = 0; i < section_line.size(); i++) { sections.push_back(Pair<String, int>(section_line[i].first, i)); diff --git a/editor/editor_help.h b/editor/editor_help.h index 83c279aec3..a690e10e7e 100644 --- a/editor/editor_help.h +++ b/editor/editor_help.h @@ -108,14 +108,14 @@ class EditorHelp : public VBoxContainer { String edited_class; - Vector<Pair<String, int> > section_line; + Vector<Pair<String, int>> section_line; Map<String, int> method_line; Map<String, int> signal_line; Map<String, int> property_line; Map<String, int> theme_property_line; Map<String, int> constant_line; Map<String, int> enum_line; - Map<String, Map<String, int> > enum_values_line; + Map<String, Map<String, int>> enum_values_line; int description_line; RichTextLabel *class_desc; @@ -175,7 +175,7 @@ public: void go_to_help(const String &p_help); void go_to_class(const String &p_class, int p_scroll = 0); - Vector<Pair<String, int> > get_sections(); + Vector<Pair<String, int>> get_sections(); void scroll_to_section(int p_section_index); void popup_search(); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index ed5a411d8b..a7540bad10 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -1454,7 +1454,7 @@ void EditorInspector::update_tree() { if (!object) return; - List<Ref<EditorInspectorPlugin> > valid_plugins; + List<Ref<EditorInspectorPlugin>> valid_plugins; for (int i = inspector_plugin_count - 1; i >= 0; i--) { //start by last, so lastly added can override newly added if (!inspector_plugins[i]->can_handle(object)) @@ -1490,7 +1490,7 @@ void EditorInspector::update_tree() { Color sscolor = get_color("prop_subsection", "Editor"); - for (List<Ref<EditorInspectorPlugin> >::Element *E = valid_plugins.front(); E; E = E->next()) { + for (List<Ref<EditorInspectorPlugin>>::Element *E = valid_plugins.front(); E; E = E->next()) { Ref<EditorInspectorPlugin> ped = E->get(); ped->parse_begin(object); _parse_added_editors(main_vbox, ped); @@ -1557,7 +1557,7 @@ void EditorInspector::update_tree() { category->set_tooltip(p.name + "::" + (class_descr_cache[type2] == "" ? "" : class_descr_cache[type2])); } - for (List<Ref<EditorInspectorPlugin> >::Element *E = valid_plugins.front(); E; E = E->next()) { + for (List<Ref<EditorInspectorPlugin>>::Element *E = valid_plugins.front(); E; E = E->next()) { Ref<EditorInspectorPlugin> ped = E->get(); ped->parse_category(object, p.name); _parse_added_editors(main_vbox, ped); @@ -1688,7 +1688,7 @@ void EditorInspector::update_tree() { String descr; bool found = false; - Map<StringName, Map<StringName, String> >::Element *E = descr_cache.find(classname); + Map<StringName, Map<StringName, String>>::Element *E = descr_cache.find(classname); if (E) { Map<StringName, String>::Element *F = E->get().find(propname); if (F) { @@ -1719,7 +1719,7 @@ void EditorInspector::update_tree() { doc_hint = descr; } - for (List<Ref<EditorInspectorPlugin> >::Element *E = valid_plugins.front(); E; E = E->next()) { + for (List<Ref<EditorInspectorPlugin>>::Element *E = valid_plugins.front(); E; E = E->next()) { Ref<EditorInspectorPlugin> ped = E->get(); bool exclusive = ped->parse_property(object, p.type, p.name, p.hint, p.hint_string, p.usage); @@ -1802,7 +1802,7 @@ void EditorInspector::update_tree() { } } - for (List<Ref<EditorInspectorPlugin> >::Element *E = valid_plugins.front(); E; E = E->next()) { + for (List<Ref<EditorInspectorPlugin>>::Element *E = valid_plugins.front(); E; E = E->next()) { Ref<EditorInspectorPlugin> ped = E->get(); ped->parse_end(); _parse_added_editors(main_vbox, ped); @@ -1933,7 +1933,7 @@ void EditorInspector::collapse_all_folding() { E->get()->fold(); } - for (Map<StringName, List<EditorProperty *> >::Element *F = editor_property_map.front(); F; F = F->next()) { + for (Map<StringName, List<EditorProperty *>>::Element *F = editor_property_map.front(); F; F = F->next()) { for (List<EditorProperty *>::Element *E = F->get().front(); E; E = E->next()) { E->get()->collapse_all_folding(); } @@ -1944,7 +1944,7 @@ void EditorInspector::expand_all_folding() { for (List<EditorInspectorSection *>::Element *E = sections.front(); E; E = E->next()) { E->get()->unfold(); } - for (Map<StringName, List<EditorProperty *> >::Element *F = editor_property_map.front(); F; F = F->next()) { + for (Map<StringName, List<EditorProperty *>>::Element *F = editor_property_map.front(); F; F = F->next()) { for (List<EditorProperty *>::Element *E = F->get().front(); E; E = E->next()) { E->get()->expand_all_folding(); } @@ -2154,7 +2154,7 @@ void EditorInspector::_property_selected(const String &p_path, int p_focusable) property_selected = p_path; property_focusable = p_focusable; //deselect the others - for (Map<StringName, List<EditorProperty *> >::Element *F = editor_property_map.front(); F; F = F->next()) { + for (Map<StringName, List<EditorProperty *>>::Element *F = editor_property_map.front(); F; F = F->next()) { if (F->key() == property_selected) continue; for (List<EditorProperty *>::Element *E = F->get().front(); E; E = E->next()) { @@ -2217,7 +2217,7 @@ void EditorInspector::_notification(int p_what) { if (refresh_countdown > 0) { refresh_countdown -= get_process_delta_time(); if (refresh_countdown <= 0) { - for (Map<StringName, List<EditorProperty *> >::Element *F = editor_property_map.front(); F; F = F->next()) { + for (Map<StringName, List<EditorProperty *>>::Element *F = editor_property_map.front(); F; F = F->next()) { for (List<EditorProperty *>::Element *E = F->get().front(); E; E = E->next()) { E->get()->update_property(); E->get()->update_reload_status(); diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index 7a1542d30f..b49a4424f6 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -261,7 +261,7 @@ class EditorInspector : public ScrollContainer { VBoxContainer *main_vbox; //map use to cache the instanced editors - Map<StringName, List<EditorProperty *> > editor_property_map; + Map<StringName, List<EditorProperty *>> editor_property_map; List<EditorInspectorSection *> sections; Set<StringName> pending; @@ -291,7 +291,7 @@ class EditorInspector : public ScrollContainer { int property_focusable; int update_scroll_request; - Map<StringName, Map<StringName, String> > descr_cache; + Map<StringName, Map<StringName, String>> descr_cache; Map<StringName, String> class_descr_cache; Set<StringName> restart_request_props; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 02ec02d77d..fd9977d409 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -547,7 +547,7 @@ void EditorNode::_on_plugin_ready(Object *p_script, const String &p_activate_nam void EditorNode::_resources_changed(const Vector<String> &p_resources) { - List<Ref<Resource> > changed; + List<Ref<Resource>> changed; int rc = p_resources.size(); for (int i = 0; i < rc; i++) { @@ -573,7 +573,7 @@ void EditorNode::_resources_changed(const Vector<String> &p_resources) { } if (changed.size()) { - for (List<Ref<Resource> >::Element *E = changed.front(); E; E = E->next()) { + for (List<Ref<Resource>>::Element *E = changed.front(); E; E = E->next()) { E->get()->reload_from_file(); } } @@ -1210,7 +1210,7 @@ bool EditorNode::_validate_scene_recursive(const String &p_filename, Node *p_nod return false; } -static bool _find_edited_resources(const Ref<Resource> &p_resource, Set<Ref<Resource> > &edited_resources) { +static bool _find_edited_resources(const Ref<Resource> &p_resource, Set<Ref<Resource>> &edited_resources) { if (p_resource->is_edited()) { edited_resources.insert(p_resource); @@ -1247,11 +1247,11 @@ int EditorNode::_save_external_resources() { flg |= ResourceSaver::FLAG_COMPRESS; flg |= ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS; - Set<Ref<Resource> > edited_subresources; + Set<Ref<Resource>> edited_subresources; int saved = 0; - List<Ref<Resource> > cached; + List<Ref<Resource>> cached; ResourceCache::get_cached_resources(&cached); - for (List<Ref<Resource> >::Element *E = cached.front(); E; E = E->next()) { + for (List<Ref<Resource>>::Element *E = cached.front(); E; E = E->next()) { Ref<Resource> res = E->get(); if (!res->get_path().is_resource_file()) @@ -1266,7 +1266,7 @@ int EditorNode::_save_external_resources() { // clear later, because user may have put the same subresource in two different resources, // which will be shared until the next reload - for (Set<Ref<Resource> >::Element *E = edited_subresources.front(); E; E = E->next()) { + for (Set<Ref<Resource>>::Element *E = edited_subresources.front(); E; E = E->next()) { Ref<Resource> res = E->get(); res->set_edited(false); } @@ -3333,7 +3333,7 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b dependency_errors.erase(lpath); //at least not self path - for (Map<String, Set<String> >::Element *E = dependency_errors.front(); E; E = E->next()) { + for (Map<String, Set<String>>::Element *E = dependency_errors.front(); E; E = E->next()) { String txt = vformat(TTR("Scene '%s' has broken dependencies:"), E->key()) + "\n"; for (Set<String>::Element *F = E->get().front(); F; F = F->next()) { @@ -3787,8 +3787,8 @@ Ref<Texture2D> EditorNode::get_class_icon(const String &p_class, const String &p return icon; } - const Map<String, Vector<EditorData::CustomType> > &p_map = EditorNode::get_editor_data().get_custom_types(); - for (const Map<String, Vector<EditorData::CustomType> >::Element *E = p_map.front(); E; E = E->next()) { + const Map<String, Vector<EditorData::CustomType>> &p_map = EditorNode::get_editor_data().get_custom_types(); + for (const Map<String, Vector<EditorData::CustomType>>::Element *E = p_map.front(); E; E = E->next()) { const Vector<EditorData::CustomType> &ct = E->value(); for (int i = 0; i < ct.size(); ++i) { if (ct[i].name == p_class) { @@ -5120,10 +5120,10 @@ void EditorNode::reload_scene(const String &p_path) { //first of all, reload internal textures, materials, meshes, etc. as they might have changed on disk - List<Ref<Resource> > cached; + List<Ref<Resource>> cached; ResourceCache::get_cached_resources(&cached); - List<Ref<Resource> > to_clear; //clear internal resources from previous scene from being used - for (List<Ref<Resource> >::Element *E = cached.front(); E; E = E->next()) { + List<Ref<Resource>> to_clear; //clear internal resources from previous scene from being used + for (List<Ref<Resource>>::Element *E = cached.front(); E; E = E->next()) { if (E->get()->get_path().begins_with(p_path + "::")) { //subresources of existing scene to_clear.push_back(E->get()); @@ -5254,9 +5254,9 @@ void EditorNode::remove_resource_conversion_plugin(const Ref<EditorResourceConve resource_conversion_plugins.erase(p_plugin); } -Vector<Ref<EditorResourceConversionPlugin> > EditorNode::find_resource_conversion_plugin(const Ref<Resource> &p_for_resource) { +Vector<Ref<EditorResourceConversionPlugin>> EditorNode::find_resource_conversion_plugin(const Ref<Resource> &p_for_resource) { - Vector<Ref<EditorResourceConversionPlugin> > ret; + Vector<Ref<EditorResourceConversionPlugin>> ret; for (int i = 0; i < resource_conversion_plugins.size(); i++) { if (resource_conversion_plugins[i].is_valid() && resource_conversion_plugins[i]->handles(p_for_resource)) { diff --git a/editor/editor_node.h b/editor/editor_node.h index e2badff88d..bd285db224 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -513,7 +513,7 @@ private: Set<FileDialog *> file_dialogs; Set<EditorFileDialog *> editor_file_dialogs; - Map<String, Ref<Texture2D> > icon_type_cache; + Map<String, Ref<Texture2D>> icon_type_cache; void _build_icon_type_cache(); bool _initializing_addons; @@ -536,7 +536,7 @@ private: void _find_node_types(Node *p_node, int &count_2d, int &count_3d); void _save_scene_with_preview(String p_file, int p_idx = -1); - Map<String, Set<String> > dependency_errors; + Map<String, Set<String>> dependency_errors; static void _dependency_error_report(void *ud, const String &p_path, const String &p_dep, const String &p_type) { EditorNode *en = (EditorNode *)ud; @@ -622,7 +622,7 @@ private: void _update_update_spinner(); - Vector<Ref<EditorResourceConversionPlugin> > resource_conversion_plugins; + Vector<Ref<EditorResourceConversionPlugin>> resource_conversion_plugins; PrintHandlerList print_handler; static void _print_handler(void *p_this, const String &p_string, bool p_error); @@ -844,7 +844,7 @@ public: void add_resource_conversion_plugin(const Ref<EditorResourceConversionPlugin> &p_plugin); void remove_resource_conversion_plugin(const Ref<EditorResourceConversionPlugin> &p_plugin); - Vector<Ref<EditorResourceConversionPlugin> > find_resource_conversion_plugin(const Ref<Resource> &p_for_resource); + Vector<Ref<EditorResourceConversionPlugin>> find_resource_conversion_plugin(const Ref<Resource> &p_for_resource); static void add_init_callback(EditorNodeInitCallback p_callback) { _init_callbacks.push_back(p_callback); } static void add_build_callback(EditorBuildCallback p_callback); diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 10ecdb19c0..5204a4d579 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -45,13 +45,13 @@ Array EditorInterface::_make_mesh_previews(const Array &p_meshes, int p_preview_size) { - Vector<Ref<Mesh> > meshes; + Vector<Ref<Mesh>> meshes; for (int i = 0; i < p_meshes.size(); i++) { meshes.push_back(p_meshes[i]); } - Vector<Ref<Texture2D> > textures = make_mesh_previews(meshes, NULL, p_preview_size); + Vector<Ref<Texture2D>> textures = make_mesh_previews(meshes, NULL, p_preview_size); Array ret; for (int i = 0; i < textures.size(); i++) { ret.push_back(textures[i]); @@ -60,7 +60,7 @@ Array EditorInterface::_make_mesh_previews(const Array &p_meshes, int p_preview_ return ret; } -Vector<Ref<Texture2D> > EditorInterface::make_mesh_previews(const Vector<Ref<Mesh> > &p_meshes, Vector<Transform> *p_transforms, int p_preview_size) { +Vector<Ref<Texture2D>> EditorInterface::make_mesh_previews(const Vector<Ref<Mesh>> &p_meshes, Vector<Transform> *p_transforms, int p_preview_size) { int size = p_preview_size; @@ -86,7 +86,7 @@ Vector<Ref<Texture2D> > EditorInterface::make_mesh_previews(const Vector<Ref<Mes EditorProgress ep("mlib", TTR("Creating Mesh Previews"), p_meshes.size()); - Vector<Ref<Texture2D> > textures; + Vector<Ref<Texture2D>> textures; for (int i = 0; i < p_meshes.size(); i++) { diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h index dee63e4322..0313ef2b26 100644 --- a/editor/editor_plugin.h +++ b/editor/editor_plugin.h @@ -98,7 +98,7 @@ public: Error save_scene(); void save_scene_as(const String &p_scene, bool p_with_preview = true); - Vector<Ref<Texture2D> > make_mesh_previews(const Vector<Ref<Mesh> > &p_meshes, Vector<Transform> *p_transforms, int p_preview_size); + Vector<Ref<Texture2D>> make_mesh_previews(const Vector<Ref<Mesh>> &p_meshes, Vector<Transform> *p_transforms, int p_preview_size); void set_main_screen_editor(const String &p_name); void set_distraction_free_mode(bool p_enter); diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp index 76dbadf67e..33877f86c2 100644 --- a/editor/editor_plugin_settings.cpp +++ b/editor/editor_plugin_settings.cpp @@ -137,19 +137,12 @@ void EditorPluginSettings::update_plugins() { item->set_metadata(1, script); item->set_text(2, author); item->set_metadata(2, description); - item->set_cell_mode(3, TreeItem::CELL_MODE_RANGE); - item->set_range_config(3, 0, 1, 1); - item->set_text(3, "Inactive,Active"); + item->set_cell_mode(3, TreeItem::CELL_MODE_CHECK); + item->set_text(3, TTR("Enable")); + bool is_active = EditorNode::get_singleton()->is_addon_plugin_enabled(d2); + item->set_checked(3, is_active); item->set_editable(3, true); item->add_button(4, get_icon("Edit", "EditorIcons"), BUTTON_PLUGIN_EDIT, false, TTR("Edit Plugin")); - - if (EditorNode::get_singleton()->is_addon_plugin_enabled(d2)) { - item->set_custom_color(3, get_color("success_color", "Editor")); - item->set_range(3, 1); - } else { - item->set_custom_color(3, get_color("disabled_font_color", "Editor")); - item->set_range(3, 0); - } } } } @@ -164,7 +157,7 @@ void EditorPluginSettings::_plugin_activity_changed() { TreeItem *ti = plugin_list->get_edited(); ERR_FAIL_COND(!ti); - bool active = ti->get_range(3); + bool active = ti->is_checked(3); String name = ti->get_metadata(0); EditorNode::get_singleton()->set_addon_plugin_enabled(name, active, true); @@ -173,14 +166,9 @@ void EditorPluginSettings::_plugin_activity_changed() { if (is_active != active) { updating = true; - ti->set_range(3, is_active ? 1 : 0); + ti->set_checked(3, is_active); updating = false; } - - if (is_active) - ti->set_custom_color(3, get_color("success_color", "Editor")); - else - ti->set_custom_color(3, get_color("disabled_font_color", "Editor")); } void EditorPluginSettings::_create_clicked() { diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 9ff34f8fb4..9a474ed4af 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -2121,7 +2121,7 @@ void EditorPropertyResource::_menu_option(int p_which) { List<PropertyInfo> property_list; res_orig->get_property_list(&property_list); - List<Pair<String, Variant> > propvalues; + List<Pair<String, Variant>> propvalues; for (List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) { @@ -2144,7 +2144,7 @@ void EditorPropertyResource::_menu_option(int p_which) { ERR_FAIL_COND(res.is_null()); - for (List<Pair<String, Variant> >::Element *E = propvalues.front(); E; E = E->next()) { + for (List<Pair<String, Variant>>::Element *E = propvalues.front(); E; E = E->next()) { Pair<String, Variant> &p = E->get(); res->set(p.first, p.second); @@ -2206,7 +2206,7 @@ void EditorPropertyResource::_menu_option(int p_which) { int to_type = p_which - CONVERT_BASE_ID; - Vector<Ref<EditorResourceConversionPlugin> > conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(res); + Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(res); ERR_FAIL_INDEX(to_type, conversions.size()); @@ -2438,7 +2438,7 @@ void EditorPropertyResource::_update_menu_items() { if (!res.is_null()) { - Vector<Ref<EditorResourceConversionPlugin> > conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(res); + Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(res); if (conversions.size()) { menu->add_separator(); } diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index 3c401a6fc7..98bc544478 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -109,9 +109,10 @@ void EditorResourcePreview::_thread_func(void *ud) { void EditorResourcePreview::_preview_ready(const String &p_str, const Ref<Texture2D> &p_texture, const Ref<Texture2D> &p_small_texture, ObjectID id, const StringName &p_func, const Variant &p_ud) { - MutexLock lock(preview_mutex); String path = p_str; { + MutexLock lock(preview_mutex); + uint32_t hash = 0; uint64_t modified_time = 0; @@ -364,7 +365,6 @@ void EditorResourcePreview::queue_edited_resource_preview(const Ref<Resource> &p cache[path_id].order = order++; p_receiver->call(p_receiver_func, path_id, cache[path_id].preview, cache[path_id].small_preview, p_userdata); - preview_mutex.unlock(); return; } @@ -391,7 +391,6 @@ void EditorResourcePreview::queue_resource_preview(const String &p_path, Object if (cache.has(p_path)) { cache[p_path].order = order++; p_receiver->call(p_receiver_func, p_path, cache[p_path].preview, cache[p_path].small_preview, p_userdata); - preview_mutex.unlock(); return; } @@ -436,9 +435,10 @@ void EditorResourcePreview::_bind_methods() { void EditorResourcePreview::check_for_invalidation(const String &p_path) { - MutexLock lock(preview_mutex); bool call_invalidated = false; { + MutexLock lock(preview_mutex); + if (cache.has(p_path)) { uint64_t modified_time = FileAccess::get_modified_time(p_path); diff --git a/editor/editor_resource_preview.h b/editor/editor_resource_preview.h index 0e1684963c..dc5a3b9c93 100644 --- a/editor/editor_resource_preview.h +++ b/editor/editor_resource_preview.h @@ -94,7 +94,7 @@ class EditorResourcePreview : public Node { static void _thread_func(void *ud); void _thread(); - Vector<Ref<EditorResourcePreviewGenerator> > preview_generators; + Vector<Ref<EditorResourcePreviewGenerator>> preview_generators; protected: static void _bind_methods(); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index ae16a50279..3f54761c15 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -125,7 +125,7 @@ bool EditorSettings::_get(const StringName &p_name, Variant &r_ret) const { if (p_name.operator String() == "shortcuts") { Array arr; - for (const Map<String, Ref<ShortCut> >::Element *E = shortcuts.front(); E; E = E->next()) { + for (const Map<String, Ref<ShortCut>>::Element *E = shortcuts.front(); E; E = E->next()) { Ref<ShortCut> sc = E->get(); @@ -1476,7 +1476,7 @@ void EditorSettings::add_shortcut(const String &p_name, Ref<ShortCut> &p_shortcu bool EditorSettings::is_shortcut(const String &p_name, const Ref<InputEvent> &p_event) const { - const Map<String, Ref<ShortCut> >::Element *E = shortcuts.find(p_name); + const Map<String, Ref<ShortCut>>::Element *E = shortcuts.find(p_name); ERR_FAIL_COND_V_MSG(!E, false, "Unknown Shortcut: " + p_name + "."); return E->get()->is_shortcut(p_event); @@ -1484,7 +1484,7 @@ bool EditorSettings::is_shortcut(const String &p_name, const Ref<InputEvent> &p_ Ref<ShortCut> EditorSettings::get_shortcut(const String &p_name) const { - const Map<String, Ref<ShortCut> >::Element *E = shortcuts.find(p_name); + const Map<String, Ref<ShortCut>>::Element *E = shortcuts.find(p_name); if (!E) return Ref<ShortCut>(); @@ -1493,7 +1493,7 @@ Ref<ShortCut> EditorSettings::get_shortcut(const String &p_name) const { void EditorSettings::get_shortcut_list(List<String> *r_shortcuts) { - for (const Map<String, Ref<ShortCut> >::Element *E = shortcuts.front(); E; E = E->next()) { + for (const Map<String, Ref<ShortCut>>::Element *E = shortcuts.front(); E; E = E->next()) { r_shortcuts->push_back(E->key()); } diff --git a/editor/editor_settings.h b/editor/editor_settings.h index d4dd19ee10..29b89ef1a8 100644 --- a/editor/editor_settings.h +++ b/editor/editor_settings.h @@ -95,7 +95,7 @@ private: int last_order; Ref<Resource> clipboard; - Map<String, Ref<ShortCut> > shortcuts; + Map<String, Ref<ShortCut>> shortcuts; String resource_path; String settings_dir; diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 6c69f46941..e9e1b3be43 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -1085,10 +1085,10 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin void FileSystemDock::_update_resource_paths_after_move(const Map<String, String> &p_renames) const { // Rename all resources loaded, be it subresources or actual resources. - List<Ref<Resource> > cached; + List<Ref<Resource>> cached; ResourceCache::get_cached_resources(&cached); - for (List<Ref<Resource> >::Element *E = cached.front(); E; E = E->next()) { + for (List<Ref<Resource>>::Element *E = cached.front(); E; E = E->next()) { Ref<Resource> r = E->get(); String base_path = r->get_path(); diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp index 2f97f4aa31..3cc6e7a50c 100644 --- a/editor/import/editor_import_collada.cpp +++ b/editor/import/editor_import_collada.cpp @@ -49,7 +49,7 @@ struct ColladaImport { Collada collada; Spatial *scene; - Vector<Ref<Animation> > animations; + Vector<Ref<Animation>> animations; struct NodeMap { //String path; @@ -73,12 +73,12 @@ struct ColladaImport { Map<String, NodeMap> node_map; //map from collada node to engine node Map<String, String> node_name_map; //map from collada node to engine node - Map<String, Ref<ArrayMesh> > mesh_cache; - Map<String, Ref<Curve3D> > curve_cache; - Map<String, Ref<Material> > material_cache; + Map<String, Ref<ArrayMesh>> mesh_cache; + Map<String, Ref<Curve3D>> curve_cache; + Map<String, Ref<Material>> material_cache; Map<Collada::Node *, Skeleton *> skeleton_map; - Map<Skeleton *, Map<String, int> > skeleton_bone_map; + Map<Skeleton *, Map<String, int>> skeleton_bone_map; Set<String> valid_animated_nodes; Vector<int> valid_animated_properties; @@ -89,7 +89,7 @@ struct ColladaImport { Error _create_scene(Collada::Node *p_node, Spatial *p_parent); Error _create_resources(Collada::Node *p_node, bool p_use_compression); Error _create_material(const String &p_target); - Error _create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<ArrayMesh> > p_morph_meshes = Vector<Ref<ArrayMesh> >(), bool p_use_compression = false, bool p_use_mesh_material = false); + Error _create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<ArrayMesh>> p_morph_meshes = Vector<Ref<ArrayMesh>>(), bool p_use_compression = false, bool p_use_mesh_material = false); Error load(const String &p_path, int p_flags, bool p_force_make_tangents = false, bool p_use_compression = false); void _fix_param_animation_tracks(); void create_animation(int p_clip, bool p_make_tracks_in_all_bones, bool p_import_value_tracks); @@ -489,7 +489,7 @@ Error ColladaImport::_create_material(const String &p_target) { return OK; } -Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<ArrayMesh> > p_morph_meshes, bool p_use_compression, bool p_use_mesh_material) { +Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<ArrayMesh>> p_morph_meshes, bool p_use_compression, bool p_use_mesh_material) { bool local_xform_mirror = p_local_xform.basis.determinant() < 0; @@ -608,7 +608,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me /* ADD WEIGHTS IF EXIST */ /************************/ - Map<int, Vector<Collada::Vertex::Weight> > pre_weights; + Map<int, Vector<Collada::Vertex::Weight>> pre_weights; bool has_weights = false; @@ -1096,7 +1096,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres String meshid; Transform apply_xform; Vector<int> bone_remap; - Vector<Ref<ArrayMesh> > morphs; + Vector<Ref<ArrayMesh>> morphs; if (ng2->controller) { @@ -1173,7 +1173,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres Ref<ArrayMesh> mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid2]; mesh->set_name(meshdata.name); - Error err = _create_mesh_surfaces(false, mesh, ng2->material_map, meshdata, apply_xform, bone_remap, skin, NULL, Vector<Ref<ArrayMesh> >(), false); + Error err = _create_mesh_surfaces(false, mesh, ng2->material_map, meshdata, apply_xform, bone_remap, skin, NULL, Vector<Ref<ArrayMesh>>(), false); ERR_FAIL_COND_V(err, err); morphs.push_back(mesh); diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp index 731d094745..398fc9ff49 100644 --- a/editor/import/editor_scene_importer_gltf.cpp +++ b/editor/import/editor_scene_importer_gltf.cpp @@ -1838,7 +1838,7 @@ Error EditorSceneImporterGLTF::_determine_skeletons(GLTFState &state) { skeleton_sets.get_representatives(groups_representatives); Vector<GLTFNodeIndex> highest_group_members; - Vector<Vector<GLTFNodeIndex> > groups; + Vector<Vector<GLTFNodeIndex>> groups; for (int i = 0; i < groups_representatives.size(); ++i) { Vector<GLTFNodeIndex> group; skeleton_sets.get_members(group, groups_representatives[i]); diff --git a/editor/import/editor_scene_importer_gltf.h b/editor/import/editor_scene_importer_gltf.h index 5d2711483b..9f354fde2d 100644 --- a/editor/import/editor_scene_importer_gltf.h +++ b/editor/import/editor_scene_importer_gltf.h @@ -284,7 +284,7 @@ class EditorSceneImporterGLTF : public EditorSceneImporter { Channel<Vector3> translation_track; Channel<Quat> rotation_track; Channel<Vector3> scale_track; - Vector<Channel<float> > weight_tracks; + Vector<Channel<float>> weight_tracks; }; String name; @@ -302,18 +302,18 @@ class EditorSceneImporterGLTF : public EditorSceneImporter { bool use_named_skin_binds; Vector<GLTFNode *> nodes; - Vector<Vector<uint8_t> > buffers; + Vector<Vector<uint8_t>> buffers; Vector<GLTFBufferView> buffer_views; Vector<GLTFAccessor> accessors; Vector<GLTFMesh> meshes; //meshes are loaded directly, no reason not to. - Vector<Ref<Material> > materials; + Vector<Ref<Material>> materials; String scene_name; Vector<int> root_nodes; Vector<GLTFTexture> textures; - Vector<Ref<Texture2D> > images; + Vector<Ref<Texture2D>> images; Vector<GLTFSkin> skins; Vector<GLTFCamera> cameras; diff --git a/editor/import/resource_importer_csv_translation.cpp b/editor/import/resource_importer_csv_translation.cpp index 3119fb088b..1d7bed3975 100644 --- a/editor/import/resource_importer_csv_translation.cpp +++ b/editor/import/resource_importer_csv_translation.cpp @@ -96,7 +96,7 @@ Error ResourceImporterCSVTranslation::import(const String &p_source_file, const ERR_FAIL_COND_V(line.size() <= 1, ERR_PARSE_ERROR); Vector<String> locales; - Vector<Ref<Translation> > translations; + Vector<Ref<Translation>> translations; for (int i = 1; i < line.size(); i++) { diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp index 7fd3bcc478..fb1782cb65 100644 --- a/editor/import/resource_importer_obj.cpp +++ b/editor/import/resource_importer_obj.cpp @@ -42,7 +42,7 @@ uint32_t EditorOBJImporter::get_import_flags() const { return IMPORT_SCENE; } -static Error _parse_material_library(const String &p_path, Map<String, Ref<StandardMaterial3D> > &material_map, List<String> *r_missing_deps) { +static Error _parse_material_library(const String &p_path, Map<String, Ref<StandardMaterial3D>> &material_map, List<String> *r_missing_deps) { FileAccessRef f = FileAccess::open(p_path, FileAccess::READ); ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, vformat("Couldn't open MTL file '%s', it may not exist or not be readable.", p_path)); @@ -203,7 +203,7 @@ static Error _parse_material_library(const String &p_path, Map<String, Ref<Stand return OK; } -static Error _parse_obj(const String &p_path, List<Ref<Mesh> > &r_meshes, bool p_single_mesh, bool p_generate_tangents, bool p_optimize, Vector3 p_scale_mesh, Vector3 p_offset_mesh, List<String> *r_missing_deps) { +static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_single_mesh, bool p_generate_tangents, bool p_optimize, Vector3 p_scale_mesh, Vector3 p_offset_mesh, List<String> *r_missing_deps) { FileAccessRef f = FileAccess::open(p_path, FileAccess::READ); ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, vformat("Couldn't open OBJ file '%s', it may not exist or not be readable.", p_path)); @@ -221,7 +221,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh> > &r_meshes, bool p Vector<Vector2> uvs; String name; - Map<String, Map<String, Ref<StandardMaterial3D> > > material_map; + Map<String, Map<String, Ref<StandardMaterial3D>>> material_map; Ref<SurfaceTool> surf_tool = memnew(SurfaceTool); surf_tool->begin(Mesh::PRIMITIVE_TRIANGLES); @@ -397,7 +397,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh> > &r_meshes, bool p current_material_library = l.replace("mtllib", "").strip_edges(); if (!material_map.has(current_material_library)) { - Map<String, Ref<StandardMaterial3D> > lib; + Map<String, Ref<StandardMaterial3D>> lib; Error err = _parse_material_library(current_material_library, lib, r_missing_deps); if (err == ERR_CANT_OPEN) { String dir = p_path.get_base_dir(); @@ -420,7 +420,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh> > &r_meshes, bool p Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) { - List<Ref<Mesh> > meshes; + List<Ref<Mesh>> meshes; Error err = _parse_obj(p_path, meshes, false, p_flags & IMPORT_GENERATE_TANGENT_ARRAYS, p_flags & IMPORT_USE_COMPRESSION, Vector3(1, 1, 1), Vector3(0, 0, 0), r_missing_deps); @@ -433,7 +433,7 @@ Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, in Spatial *scene = memnew(Spatial); - for (List<Ref<Mesh> >::Element *E = meshes.front(); E; E = E->next()) { + for (List<Ref<Mesh>>::Element *E = meshes.front(); E; E = E->next()) { MeshInstance *mi = memnew(MeshInstance); mi->set_mesh(E->get()); @@ -500,7 +500,7 @@ bool ResourceImporterOBJ::get_option_visibility(const String &p_option, const Ma Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { - List<Ref<Mesh> > meshes; + List<Ref<Mesh>> meshes; Error err = _parse_obj(p_source_file, meshes, true, p_options["generate_tangents"], p_options["optimize_mesh"], p_options["scale_mesh"], p_options["offset_mesh"], NULL); diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 5651197fa3..94a6fee6b7 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -170,7 +170,7 @@ String ResourceImporterScene::get_visible_name() const { void ResourceImporterScene::get_recognized_extensions(List<String> *p_extensions) const { - for (Set<Ref<EditorSceneImporter> >::Element *E = importers.front(); E; E = E->next()) { + for (Set<Ref<EditorSceneImporter>>::Element *E = importers.front(); E; E = E->next()) { E->get()->get_extensions(p_extensions); } } @@ -276,7 +276,7 @@ static String _fixstr(const String &p_what, const String &p_str) { return what; } -static void _gen_shape_list(const Ref<Mesh> &mesh, List<Ref<Shape> > &r_shape_list, bool p_convex) { +static void _gen_shape_list(const Ref<Mesh> &mesh, List<Ref<Shape>> &r_shape_list, bool p_convex) { if (!p_convex) { @@ -284,7 +284,7 @@ static void _gen_shape_list(const Ref<Mesh> &mesh, List<Ref<Shape> > &r_shape_li r_shape_list.push_back(shape); } else { - Vector<Ref<Shape> > cd = mesh->convex_decompose(); + Vector<Ref<Shape>> cd = mesh->convex_decompose(); if (cd.size()) { for (int i = 0; i < cd.size(); i++) { r_shape_list.push_back(cd[i]); @@ -293,7 +293,7 @@ static void _gen_shape_list(const Ref<Mesh> &mesh, List<Ref<Shape> > &r_shape_li } } -Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, List<Ref<Shape> > > &collision_map, LightBakeMode p_light_bake_mode) { +Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, List<Ref<Shape>>> &collision_map, LightBakeMode p_light_bake_mode) { // children first for (int i = 0; i < p_node->get_child_count(); i++) { @@ -382,7 +382,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh> Ref<Mesh> mesh = mi->get_mesh(); if (mesh.is_valid()) { - List<Ref<Shape> > shapes; + List<Ref<Shape>> shapes; String fixed_name; if (collision_map.has(mesh)) { shapes = collision_map[mesh]; @@ -412,7 +412,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh> p_node = col; int idx = 0; - for (List<Ref<Shape> >::Element *E = shapes.front(); E; E = E->next()) { + for (List<Ref<Shape>>::Element *E = shapes.front(); E; E = E->next()) { CollisionShape *cshape = memnew(CollisionShape); cshape->set_shape(E->get()); @@ -468,7 +468,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh> Ref<Mesh> mesh = mi->get_mesh(); if (mesh.is_valid()) { - List<Ref<Shape> > shapes; + List<Ref<Shape>> shapes; if (collision_map.has(mesh)) { shapes = collision_map[mesh]; } else { @@ -486,7 +486,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh> mi->set_owner(rigid_body->get_owner()); int idx = 0; - for (List<Ref<Shape> >::Element *E = shapes.front(); E; E = E->next()) { + for (List<Ref<Shape>>::Element *E = shapes.front(); E; E = E->next()) { CollisionShape *cshape = memnew(CollisionShape); cshape->set_shape(E->get()); @@ -505,7 +505,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh> Ref<Mesh> mesh = mi->get_mesh(); if (mesh.is_valid()) { - List<Ref<Shape> > shapes; + List<Ref<Shape>> shapes; String fixed_name; if (collision_map.has(mesh)) { shapes = collision_map[mesh]; @@ -536,7 +536,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh> col->set_owner(mi->get_owner()); int idx = 0; - for (List<Ref<Shape> >::Element *E = shapes.front(); E; E = E->next()) { + for (List<Ref<Shape>>::Element *E = shapes.front(); E; E = E->next()) { CollisionShape *cshape = memnew(CollisionShape); cshape->set_shape(E->get()); @@ -618,7 +618,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh> Ref<ArrayMesh> mesh = mi->get_mesh(); if (!mesh.is_null()) { - List<Ref<Shape> > shapes; + List<Ref<Shape>> shapes; if (collision_map.has(mesh)) { shapes = collision_map[mesh]; } else if (_teststr(mesh->get_name(), "col")) { @@ -638,7 +638,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh> col->set_owner(p_node->get_owner()); int idx = 0; - for (List<Ref<Shape> >::Element *E = shapes.front(); E; E = E->next()) { + for (List<Ref<Shape>>::Element *E = shapes.front(); E; E = E->next()) { CollisionShape *cshape = memnew(CollisionShape); cshape->set_shape(E->get()); @@ -957,7 +957,7 @@ void ResourceImporterScene::_find_meshes(Node *p_node, Map<Ref<ArrayMesh>, Trans } } -void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_animations_as_text, bool p_keep_animations, bool p_make_materials, bool p_materials_as_text, bool p_keep_materials, bool p_make_meshes, bool p_meshes_as_text, Map<Ref<Animation>, Ref<Animation> > &p_animations, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes) { +void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_animations_as_text, bool p_keep_animations, bool p_make_materials, bool p_materials_as_text, bool p_keep_materials, bool p_make_meshes, bool p_meshes_as_text, Map<Ref<Animation>, Ref<Animation>> &p_animations, Map<Ref<Material>, Ref<Material>> &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh>> &p_meshes) { List<PropertyInfo> pi; @@ -1209,7 +1209,7 @@ Node *ResourceImporterScene::import_scene_from_other_importer(EditorSceneImporte Ref<EditorSceneImporter> importer; String ext = p_path.get_extension().to_lower(); - for (Set<Ref<EditorSceneImporter> >::Element *E = importers.front(); E; E = E->next()) { + for (Set<Ref<EditorSceneImporter>>::Element *E = importers.front(); E; E = E->next()) { if (E->get().ptr() == p_exception) continue; @@ -1241,7 +1241,7 @@ Ref<Animation> ResourceImporterScene::import_animation_from_other_importer(Edito Ref<EditorSceneImporter> importer; String ext = p_path.get_extension().to_lower(); - for (Set<Ref<EditorSceneImporter> >::Element *E = importers.front(); E; E = E->next()) { + for (Set<Ref<EditorSceneImporter>>::Element *E = importers.front(); E; E = E->next()) { if (E->get().ptr() == p_exception) continue; @@ -1276,7 +1276,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p EditorProgress progress("import", TTR("Import Scene"), 104); progress.step(TTR("Importing Scene..."), 0); - for (Set<Ref<EditorSceneImporter> >::Element *E = importers.front(); E; E = E->next()) { + for (Set<Ref<EditorSceneImporter>>::Element *E = importers.front(); E; E = E->next()) { List<String> extensions; E->get()->get_extensions(&extensions); @@ -1368,7 +1368,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p float anim_optimizer_maxang = p_options["animation/optimizer/max_angle"]; int light_bake_mode = p_options["meshes/light_baking"]; - Map<Ref<Mesh>, List<Ref<Shape> > > collision_map; + Map<Ref<Mesh>, List<Ref<Shape>>> collision_map; scene = _fix_node(scene, scene, collision_map, LightBakeMode(light_bake_mode)); @@ -1456,9 +1456,9 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p } if (external_animations || external_materials || external_meshes) { - Map<Ref<Animation>, Ref<Animation> > anim_map; - Map<Ref<Material>, Ref<Material> > mat_map; - Map<Ref<ArrayMesh>, Ref<ArrayMesh> > mesh_map; + Map<Ref<Animation>, Ref<Animation>> anim_map; + Map<Ref<Material>, Ref<Material>> mat_map; + Map<Ref<ArrayMesh>, Ref<ArrayMesh>> mesh_map; bool keep_materials = bool(p_options["materials/keep_on_reimport"]); diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index 20e7af15b5..6d1043eb28 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -93,7 +93,7 @@ public: class ResourceImporterScene : public ResourceImporter { GDCLASS(ResourceImporterScene, ResourceImporter); - Set<Ref<EditorSceneImporter> > importers; + Set<Ref<EditorSceneImporter>> importers; static ResourceImporterScene *singleton; @@ -125,7 +125,7 @@ class ResourceImporterScene : public ResourceImporter { public: static ResourceImporterScene *get_singleton() { return singleton; } - const Set<Ref<EditorSceneImporter> > &get_importers() const { return importers; } + const Set<Ref<EditorSceneImporter>> &get_importers() const { return importers; } void add_importer(Ref<EditorSceneImporter> p_importer) { importers.insert(p_importer); } void remove_importer(Ref<EditorSceneImporter> p_importer) { importers.erase(p_importer); } @@ -145,9 +145,9 @@ public: void _find_meshes(Node *p_node, Map<Ref<ArrayMesh>, Transform> &meshes); - void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_animations_as_text, bool p_keep_animations, bool p_make_materials, bool p_materials_as_text, bool p_keep_materials, bool p_make_meshes, bool p_meshes_as_text, Map<Ref<Animation>, Ref<Animation> > &p_animations, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes); + void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_animations_as_text, bool p_keep_animations, bool p_make_materials, bool p_materials_as_text, bool p_keep_materials, bool p_make_meshes, bool p_meshes_as_text, Map<Ref<Animation>, Ref<Animation>> &p_animations, Map<Ref<Material>, Ref<Material>> &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh>> &p_meshes); - Node *_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, List<Ref<Shape> > > &collision_map, LightBakeMode p_light_bake_mode); + Node *_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, List<Ref<Shape>>> &collision_map, LightBakeMode p_light_bake_mode); void _create_clips(Node *scene, const Array &p_clips, bool p_bake_all); void _filter_anim_tracks(Ref<Animation> anim, Set<String> &keep); diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index 92ecda8508..0090d30b9c 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -350,7 +350,7 @@ void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String f->store_32(flags); f->store_32(p_limit_mipmap); - //reserverd for future use + //reserved for future use f->store_32(0); f->store_32(0); f->store_32(0); diff --git a/editor/import/resource_importer_texture_atlas.cpp b/editor/import/resource_importer_texture_atlas.cpp index 3172cc7279..2765bb7fae 100644 --- a/editor/import/resource_importer_texture_atlas.cpp +++ b/editor/import/resource_importer_texture_atlas.cpp @@ -192,7 +192,7 @@ static void _plot_triangle(Vector2 *vertices, const Vector2 &p_offset, bool p_tr } } -Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file, const Map<String, Map<StringName, Variant> > &p_source_file_options, const Map<String, String> &p_base_paths) { +Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file, const Map<String, Map<StringName, Variant>> &p_source_file_options, const Map<String, String> &p_base_paths) { ERR_FAIL_COND_V(p_source_file_options.size() == 0, ERR_BUG); //should never happen @@ -202,7 +202,7 @@ Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file pack_data_files.resize(p_source_file_options.size()); int idx = 0; - for (const Map<String, Map<StringName, Variant> >::Element *E = p_source_file_options.front(); E; E = E->next(), idx++) { + for (const Map<String, Map<StringName, Variant>>::Element *E = p_source_file_options.front(); E; E = E->next(), idx++) { PackData &pack_data = pack_data_files.write[idx]; const String &source = E->key(); @@ -251,7 +251,7 @@ Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file Ref<BitMap> bit_map; bit_map.instance(); bit_map->create_from_image_alpha(image); - Vector<Vector<Vector2> > polygons = bit_map->clip_opaque_to_polygons(Rect2(0, 0, image->get_width(), image->get_height())); + Vector<Vector<Vector2>> polygons = bit_map->clip_opaque_to_polygons(Rect2(0, 0, image->get_width(), image->get_height())); for (int j = 0; j < polygons.size(); j++) { @@ -323,7 +323,7 @@ Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file //save the images idx = 0; - for (const Map<String, Map<StringName, Variant> >::Element *E = p_source_file_options.front(); E; E = E->next(), idx++) { + for (const Map<String, Map<StringName, Variant>>::Element *E = p_source_file_options.front(); E; E = E->next(), idx++) { PackData &pack_data = pack_data_files.write[idx]; diff --git a/editor/import/resource_importer_texture_atlas.h b/editor/import/resource_importer_texture_atlas.h index e455a157cf..a36cae5872 100644 --- a/editor/import/resource_importer_texture_atlas.h +++ b/editor/import/resource_importer_texture_atlas.h @@ -40,7 +40,7 @@ class ResourceImporterTextureAtlas : public ResourceImporter { Rect2 region; bool is_mesh; Vector<int> chart_pieces; //one for region, many for mesh - Vector<Vector<Vector2> > chart_vertices; //for mesh + Vector<Vector<Vector2>> chart_vertices; //for mesh Ref<Image> image; }; @@ -64,7 +64,7 @@ public: virtual String get_option_group_file() const; virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL); - virtual Error import_group_file(const String &p_group_file, const Map<String, Map<StringName, Variant> > &p_source_file_options, const Map<String, String> &p_base_paths); + virtual Error import_group_file(const String &p_group_file, const Map<String, Map<StringName, Variant>> &p_source_file_options, const Map<String, String> &p_base_paths); ResourceImporterTextureAtlas(); }; diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp index 3ef88105fe..e2e68f0f41 100644 --- a/editor/import_dock.cpp +++ b/editor/import_dock.cpp @@ -112,19 +112,19 @@ void ImportDock::set_edit_path(const String &p_path) { _update_options(config); - List<Ref<ResourceImporter> > importers; + List<Ref<ResourceImporter>> importers; ResourceFormatImporter::get_singleton()->get_importers_for_extension(p_path.get_extension(), &importers); - List<Pair<String, String> > importer_names; + List<Pair<String, String>> importer_names; - for (List<Ref<ResourceImporter> >::Element *E = importers.front(); E; E = E->next()) { + for (List<Ref<ResourceImporter>>::Element *E = importers.front(); E; E = E->next()) { importer_names.push_back(Pair<String, String>(E->get()->get_visible_name(), E->get()->get_importer_name())); } - importer_names.sort_custom<PairSort<String, String> >(); + importer_names.sort_custom<PairSort<String, String>>(); import_as->clear(); - for (List<Pair<String, String> >::Element *E = importer_names.front(); E; E = E->next()) { + for (List<Pair<String, String>>::Element *E = importer_names.front(); E; E = E->next()) { import_as->add_item(E->get().first); import_as->set_item_metadata(import_as->get_item_count() - 1, E->get().second); if (E->get().second == params->importer->get_importer_name()) { @@ -240,19 +240,19 @@ void ImportDock::set_edit_multiple_paths(const Vector<String> &p_paths) { params->update(); - List<Ref<ResourceImporter> > importers; + List<Ref<ResourceImporter>> importers; ResourceFormatImporter::get_singleton()->get_importers_for_extension(p_paths[0].get_extension(), &importers); - List<Pair<String, String> > importer_names; + List<Pair<String, String>> importer_names; - for (List<Ref<ResourceImporter> >::Element *E = importers.front(); E; E = E->next()) { + for (List<Ref<ResourceImporter>>::Element *E = importers.front(); E; E = E->next()) { importer_names.push_back(Pair<String, String>(E->get()->get_visible_name(), E->get()->get_importer_name())); } - importer_names.sort_custom<PairSort<String, String> >(); + importer_names.sort_custom<PairSort<String, String>>(); import_as->clear(); - for (List<Pair<String, String> >::Element *E = importer_names.front(); E; E = E->next()) { + for (List<Pair<String, String>>::Element *E = importer_names.front(); E; E = E->next()) { import_as->add_item(E->get().first); import_as->set_item_metadata(import_as->get_item_count() - 1, E->get().second); if (E->get().second == params->importer->get_importer_name()) { diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index 5e53adf471..e79909fae1 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -536,7 +536,7 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano updating = true; Set<String> paths; - HashMap<String, Set<String> > types; + HashMap<String, Set<String>> types; { List<StringName> animations; player->get_animation_list(&animations); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 5629e3854d..6e1166bb37 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -2028,7 +2028,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { if (m.is_valid()) { // Save the ik chain for reapplying before IK solve - Vector<List<Dictionary> > all_bones_ik_states; + Vector<List<Dictionary>> all_bones_ik_states; for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { List<Dictionary> bones_ik_states; _save_canvas_item_ik_chain(E->get(), NULL, &bones_ik_states); @@ -2130,7 +2130,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { if (drag_selection.size() > 0) { // Save the ik chain for reapplying before IK solve - Vector<List<Dictionary> > all_bones_ik_states; + Vector<List<Dictionary>> all_bones_ik_states; for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { List<Dictionary> bones_ik_states; _save_canvas_item_ik_chain(E->get(), NULL, &bones_ik_states); diff --git a/editor/plugins/mesh_instance_editor_plugin.cpp b/editor/plugins/mesh_instance_editor_plugin.cpp index e5b948aad7..6025e7dd9d 100644 --- a/editor/plugins/mesh_instance_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_editor_plugin.cpp @@ -196,7 +196,7 @@ void MeshInstanceEditor::_menu_option(int p_option) { return; } - Vector<Ref<Shape> > shapes = mesh->convex_decompose(); + Vector<Ref<Shape>> shapes = mesh->convex_decompose(); if (!shapes.size()) { err_dialog->set_text(TTR("Couldn't create any collision shapes.")); diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp index 71976d509b..4e63a498b8 100644 --- a/editor/plugins/mesh_library_editor_plugin.cpp +++ b/editor/plugins/mesh_library_editor_plugin.cpp @@ -170,7 +170,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, if (1) { - Vector<Ref<Mesh> > meshes; + Vector<Ref<Mesh>> meshes; Vector<Transform> transforms; Vector<int> ids = p_library->get_item_list(); for (int i = 0; i < ids.size(); i++) { @@ -182,7 +182,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, } } - Vector<Ref<Texture2D> > textures = EditorInterface::get_singleton()->make_mesh_previews(meshes, &transforms, EditorSettings::get_singleton()->get("editors/grid_map/preview_size")); + Vector<Ref<Texture2D>> textures = EditorInterface::get_singleton()->make_mesh_previews(meshes, &transforms, EditorSettings::get_singleton()->get("editors/grid_map/preview_size")); int j = 0; for (int i = 0; i < ids.size(); i++) { diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index bb03cad285..b3f78b5406 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -969,7 +969,7 @@ Ref<Script> ScriptEditor::_get_current_script() { Array ScriptEditor::_get_open_scripts() const { Array ret; - Vector<Ref<Script> > scripts = get_open_scripts(); + Vector<Ref<Script>> scripts = get_open_scripts(); int scrits_amount = scripts.size(); for (int idx_script = 0; idx_script < scrits_amount; idx_script++) { ret.push_back(scripts[idx_script]); @@ -1571,7 +1571,7 @@ void ScriptEditor::ensure_select_current() { _update_selected_editor_menu(); } -void ScriptEditor::_find_scripts(Node *p_base, Node *p_current, Set<Ref<Script> > &used) { +void ScriptEditor::_find_scripts(Node *p_base, Node *p_current, Set<Ref<Script>> &used) { if (p_current != p_base && p_current->get_owner() != p_base) return; @@ -1704,7 +1704,7 @@ void ScriptEditor::_update_help_overview() { return; } - Vector<Pair<String, int> > sections = se->get_sections(); + Vector<Pair<String, int>> sections = se->get_sections(); for (int i = 0; i < sections.size(); i++) { help_overview->add_item(sections[i].first); help_overview->set_item_metadata(i, sections[i].second); @@ -1757,7 +1757,7 @@ void ScriptEditor::_update_script_names() { if (restoring_layout) return; - Set<Ref<Script> > used; + Set<Ref<Script>> used; Node *edited = EditorNode::get_singleton()->get_edited_scene(); if (edited) { _find_scripts(edited, edited, used); @@ -2861,9 +2861,9 @@ void ScriptEditor::_history_back() { } } -Vector<Ref<Script> > ScriptEditor::get_open_scripts() const { +Vector<Ref<Script>> ScriptEditor::get_open_scripts() const { - Vector<Ref<Script> > out_scripts = Vector<Ref<Script> >(); + Vector<Ref<Script>> out_scripts = Vector<Ref<Script>>(); for (int i = 0; i < tab_container->get_child_count(); i++) { ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i)); diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index b4b4f33fc5..81f9595264 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -351,7 +351,7 @@ class ScriptEditor : public PanelContainer { void _update_help_overview(); void _help_overview_selected(int p_idx); - void _find_scripts(Node *p_base, Node *p_current, Set<Ref<Script> > &used); + void _find_scripts(Node *p_base, Node *p_current, Set<Ref<Script>> &used); void _tree_changed(); @@ -429,7 +429,7 @@ public: void get_window_layout(Ref<ConfigFile> p_layout); void set_scene_root_script(Ref<Script> p_script); - Vector<Ref<Script> > get_open_scripts() const; + Vector<Ref<Script>> get_open_scripts() const; bool script_goto_method(Ref<Script> p_script, const String &p_method); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 02168a4c97..176df7efb8 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -759,7 +759,7 @@ static Node *_find_node_for_script(Node *p_base, Node *p_current, const Ref<Scri return NULL; } -static void _find_changed_scripts_for_external_editor(Node *p_base, Node *p_current, Set<Ref<Script> > &r_scripts) { +static void _find_changed_scripts_for_external_editor(Node *p_base, Node *p_current, Set<Ref<Script>> &r_scripts) { if (p_current->get_owner() != p_base && p_base != p_current) return; @@ -780,14 +780,14 @@ void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_fo ERR_FAIL_COND(!get_tree()); - Set<Ref<Script> > scripts; + Set<Ref<Script>> scripts; Node *base = get_tree()->get_edited_scene_root(); if (base) { _find_changed_scripts_for_external_editor(base, base, scripts); } - for (Set<Ref<Script> >::Element *E = scripts.front(); E; E = E->next()) { + for (Set<Ref<Script>>::Element *E = scripts.front(); E; E = E->next()) { Ref<Script> script = E->get(); @@ -980,6 +980,23 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c } } +void ScriptTextEditor::_validate_symbol(const String &p_symbol) { + + TextEdit *text_edit = code_editor->get_text_edit(); + + Node *base = get_tree()->get_edited_scene_root(); + if (base) { + base = _find_node_for_script(base, base, script); + } + + ScriptLanguage::LookupResult result; + if (ScriptServer::is_global_class(p_symbol) || p_symbol.is_resource_file() || script->get_language()->lookup_code(code_editor->get_text_edit()->get_text_for_lookup_completion(), p_symbol, script->get_path(), base, result) == OK) { + text_edit->set_highlighted_word(p_symbol); + } else { + text_edit->set_highlighted_word(String()); + } +} + void ScriptTextEditor::update_toggle_scripts_button() { if (code_editor != NULL) { code_editor->update_toggle_scripts_button(); @@ -1769,6 +1786,7 @@ ScriptTextEditor::ScriptTextEditor() { code_editor->set_code_complete_func(_code_complete_scripts, this); code_editor->get_text_edit()->connect("breakpoint_toggled", callable_mp(this, &ScriptTextEditor::_breakpoint_toggled)); code_editor->get_text_edit()->connect("symbol_lookup", callable_mp(this, &ScriptTextEditor::_lookup_symbol)); + code_editor->get_text_edit()->connect("symbol_validate", callable_mp(this, &ScriptTextEditor::_validate_symbol)); code_editor->get_text_edit()->connect("info_clicked", callable_mp(this, &ScriptTextEditor::_lookup_connections)); code_editor->set_v_size_flags(SIZE_EXPAND_FILL); code_editor->show_toggle_scripts_button(); diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h index e23160d029..d2f0b310e6 100644 --- a/editor/plugins/script_text_editor.h +++ b/editor/plugins/script_text_editor.h @@ -178,6 +178,7 @@ protected: void _goto_line(int p_line) { goto_line(p_line); } void _lookup_symbol(const String &p_symbol, int p_row, int p_column); + void _validate_symbol(const String &p_symbol); void _lookup_connections(int p_row, String p_method); diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 647d64c627..c305c181cc 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -496,7 +496,7 @@ ObjectID SpatialEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, Vector2 shrinked_pos = p_pos / viewport_container->get_stretch_shrink(); Vector<ObjectID> instances = VisualServer::get_singleton()->instances_cull_ray(pos, ray, get_tree()->get_root()->get_world()->get_scenario()); - Set<Ref<EditorSpatialGizmo> > found_gizmos; + Set<Ref<EditorSpatialGizmo>> found_gizmos; Node *edited_scene = get_tree()->get_edited_scene_root(); ObjectID closest; @@ -563,7 +563,7 @@ void SpatialEditorViewport::_find_items_at_pos(const Point2 &p_pos, bool &r_incl Vector3 pos = _get_ray_pos(p_pos); Vector<ObjectID> instances = VisualServer::get_singleton()->instances_cull_ray(pos, ray, get_tree()->get_root()->get_world()->get_scenario()); - Set<Ref<EditorSpatialGizmo> > found_gizmos; + Set<Ref<EditorSpatialGizmo>> found_gizmos; r_includes_current = false; @@ -2416,11 +2416,18 @@ void SpatialEditorViewport::_notification(int p_what) { if (!se) continue; + Transform t = sp->get_global_gizmo_transform(); + + exist = true; + if (se->last_xform == t) + continue; + changed = true; + se->last_xform = t; + VisualInstance *vi = Object::cast_to<VisualInstance>(sp); se->aabb = vi ? vi->get_aabb() : _calculate_spatial_bounds(sp); - Transform t = sp->get_global_gizmo_transform(); t.translate(se->aabb.position); // apply AABB scaling before item's global transform @@ -2428,11 +2435,6 @@ void SpatialEditorViewport::_notification(int p_what) { aabb_s.scale(se->aabb.size); t.basis = t.basis * aabb_s; - exist = true; - if (se->last_xform == t) - continue; - changed = true; - se->last_xform = t; VisualServer::get_singleton()->instance_set_transform(se->sbox_instance, t); } @@ -3475,7 +3477,7 @@ Vector3 SpatialEditorViewport::_get_instance_position(const Point2 &p_pos) const Vector3 world_pos = _get_ray_pos(p_pos); Vector<ObjectID> instances = VisualServer::get_singleton()->instances_cull_ray(world_pos, world_ray, get_tree()->get_root()->get_world()->get_scenario()); - Set<Ref<EditorSpatialGizmo> > found_gizmos; + Set<Ref<EditorSpatialGizmo>> found_gizmos; float closest_dist = MAX_DISTANCE; @@ -6241,6 +6243,10 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { settings_zfar->set_value(EDITOR_DEF("editors/3d/default_z_far", 1500)); settings_vbc->add_margin_child(TTR("View Z-Far:"), settings_zfar); + for (uint32_t i = 0; i < VIEWPORTS_COUNT; ++i) { + settings_dialog->connect("confirmed", callable_mp(viewports[i], &SpatialEditorViewport::_update_camera), varray(0.0)); + } + /* XFORM DIALOG */ xform_dialog = memnew(ConfirmationDialog); @@ -6465,7 +6471,7 @@ void EditorSpatialGizmoPlugin::create_material(const String &p_name, const Color Color instanced_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instanced", Color(0.7, 0.7, 0.7, 0.6)); - Vector<Ref<StandardMaterial3D> > mats; + Vector<Ref<StandardMaterial3D>> mats; for (int i = 0; i < 4; i++) { bool selected = i % 2 == 1; @@ -6507,7 +6513,7 @@ void EditorSpatialGizmoPlugin::create_icon_material(const String &p_name, const Color instanced_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instanced", Color(0.7, 0.7, 0.7, 0.6)); - Vector<Ref<StandardMaterial3D> > icons; + Vector<Ref<StandardMaterial3D>> icons; for (int i = 0; i < 4; i++) { bool selected = i % 2 == 1; @@ -6562,12 +6568,12 @@ void EditorSpatialGizmoPlugin::create_handle_material(const String &p_name, bool handle_material->set_on_top_of_alpha(); } - materials[p_name] = Vector<Ref<StandardMaterial3D> >(); + materials[p_name] = Vector<Ref<StandardMaterial3D>>(); materials[p_name].push_back(handle_material); } void EditorSpatialGizmoPlugin::add_material(const String &p_name, Ref<StandardMaterial3D> p_material) { - materials[p_name] = Vector<Ref<StandardMaterial3D> >(); + materials[p_name] = Vector<Ref<StandardMaterial3D>>(); materials[p_name].push_back(p_material); } diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h index 489bce1e15..9f78efacaf 100644 --- a/editor/plugins/spatial_editor_plugin.h +++ b/editor/plugins/spatial_editor_plugin.h @@ -712,8 +712,8 @@ private: static SpatialEditor *singleton; void _node_removed(Node *p_node); - Vector<Ref<EditorSpatialGizmoPlugin> > gizmo_plugins_by_priority; - Vector<Ref<EditorSpatialGizmoPlugin> > gizmo_plugins_by_name; + Vector<Ref<EditorSpatialGizmoPlugin>> gizmo_plugins_by_priority; + Vector<Ref<EditorSpatialGizmoPlugin>> gizmo_plugins_by_name; void _register_all_gizmos(); @@ -840,7 +840,7 @@ public: private: int current_state; List<EditorSpatialGizmo *> current_gizmos; - HashMap<String, Vector<Ref<StandardMaterial3D> > > materials; + HashMap<String, Vector<Ref<StandardMaterial3D>>> materials; protected: static void _bind_methods(); diff --git a/editor/plugins/sprite_editor_plugin.cpp b/editor/plugins/sprite_editor_plugin.cpp index 135807e88c..2897341f06 100644 --- a/editor/plugins/sprite_editor_plugin.cpp +++ b/editor/plugins/sprite_editor_plugin.cpp @@ -204,7 +204,7 @@ void SpriteEditor::_update_mesh_data() { float epsilon = simplification->get_value(); - Vector<Vector<Vector2> > lines = bm->clip_opaque_to_polygons(rect, epsilon); + Vector<Vector<Vector2>> lines = bm->clip_opaque_to_polygons(rect, epsilon); uv_lines.clear(); diff --git a/editor/plugins/sprite_editor_plugin.h b/editor/plugins/sprite_editor_plugin.h index 13177c9142..998851b6ad 100644 --- a/editor/plugins/sprite_editor_plugin.h +++ b/editor/plugins/sprite_editor_plugin.h @@ -60,8 +60,8 @@ class SpriteEditor : public Control { ConfirmationDialog *debug_uv_dialog; Control *debug_uv; Vector<Vector2> uv_lines; - Vector<Vector<Vector2> > outline_lines; - Vector<Vector<Vector2> > computed_outline_lines; + Vector<Vector<Vector2>> outline_lines; + Vector<Vector<Vector2>> computed_outline_lines; Vector<Vector2> computed_vertices; Vector<Vector2> computed_uv; Vector<int> computed_indices; diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 5d615c7553..e6b0e3142c 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -249,7 +249,7 @@ void SpriteFramesEditor::_file_load_request(const Vector<String> &p_path, int p_ ERR_FAIL_COND(!frames->has_animation(edited_anim)); - List<Ref<Texture2D> > resources; + List<Ref<Texture2D>> resources; for (int i = 0; i < p_path.size(); i++) { @@ -278,7 +278,7 @@ void SpriteFramesEditor::_file_load_request(const Vector<String> &p_path, int p_ int count = 0; - for (List<Ref<Texture2D> >::Element *E = resources.front(); E; E = E->next()) { + for (List<Ref<Texture2D>>::Element *E = resources.front(); E; E = E->next()) { undo_redo->add_do_method(frames, "add_frame", edited_anim, E->get(), p_at_pos == -1 ? -1 : p_at_pos + count); undo_redo->add_undo_method(frames, "remove_frame", edited_anim, p_at_pos == -1 ? fc : p_at_pos); diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h index d877cf9436..edc55071b7 100644 --- a/editor/plugins/texture_region_editor_plugin.h +++ b/editor/plugins/texture_region_editor_plugin.h @@ -94,7 +94,7 @@ class TextureRegionEditor : public VBoxContainer { Rect2 rect_prev; float prev_margin; int edited_margin; - Map<RID, List<Rect2> > cache_map; + Map<RID, List<Rect2>> cache_map; List<Rect2> autoslice_cache; bool autoslice_is_dirty; diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index d5b52e9711..aa5caf6658 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -120,12 +120,12 @@ struct _TECategory { bool operator<(const Item<T> &p) const { return name < p.name; } }; - Set<RefItem<StyleBox> > stylebox_items; - Set<RefItem<Font> > font_items; - Set<RefItem<Texture2D> > icon_items; + Set<RefItem<StyleBox>> stylebox_items; + Set<RefItem<Font>> font_items; + Set<RefItem<Texture2D>> icon_items; - Set<Item<Color> > color_items; - Set<Item<int> > constant_items; + Set<Item<Color>> color_items; + Set<Item<int>> constant_items; }; void ThemeEditor::_save_template_cbk(String fname) { @@ -275,7 +275,7 @@ void ThemeEditor::_save_template_cbk(String fname) { if (tc.stylebox_items.size()) file->store_line("\n; StyleBox Items:\n"); - for (Set<_TECategory::RefItem<StyleBox> >::Element *F = tc.stylebox_items.front(); F; F = F->next()) { + for (Set<_TECategory::RefItem<StyleBox>>::Element *F = tc.stylebox_items.front(); F; F = F->next()) { file->store_line(E->key() + "." + F->get().name + " = default"); } @@ -283,7 +283,7 @@ void ThemeEditor::_save_template_cbk(String fname) { if (tc.font_items.size()) file->store_line("\n; Font Items:\n"); - for (Set<_TECategory::RefItem<Font> >::Element *F = tc.font_items.front(); F; F = F->next()) { + for (Set<_TECategory::RefItem<Font>>::Element *F = tc.font_items.front(); F; F = F->next()) { file->store_line(E->key() + "." + F->get().name + " = default"); } @@ -291,7 +291,7 @@ void ThemeEditor::_save_template_cbk(String fname) { if (tc.icon_items.size()) file->store_line("\n; Icon Items:\n"); - for (Set<_TECategory::RefItem<Texture2D> >::Element *F = tc.icon_items.front(); F; F = F->next()) { + for (Set<_TECategory::RefItem<Texture2D>>::Element *F = tc.icon_items.front(); F; F = F->next()) { file->store_line(E->key() + "." + F->get().name + " = default"); } @@ -299,7 +299,7 @@ void ThemeEditor::_save_template_cbk(String fname) { if (tc.color_items.size()) file->store_line("\n; Color Items:\n"); - for (Set<_TECategory::Item<Color> >::Element *F = tc.color_items.front(); F; F = F->next()) { + for (Set<_TECategory::Item<Color>>::Element *F = tc.color_items.front(); F; F = F->next()) { file->store_line(E->key() + "." + F->get().name + " = default"); } @@ -307,7 +307,7 @@ void ThemeEditor::_save_template_cbk(String fname) { if (tc.constant_items.size()) file->store_line("\n; Constant Items:\n"); - for (Set<_TECategory::Item<int> >::Element *F = tc.constant_items.front(); F; F = F->next()) { + for (Set<_TECategory::Item<int>>::Element *F = tc.constant_items.front(); F; F = F->next()) { file->store_line(E->key() + "." + F->get().name + " = default"); } diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index d23b037ed4..a5a667802e 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -2350,12 +2350,12 @@ void TileSetEditor::_undo_tile_removal(int p_id) { undo_redo->add_undo_method(tileset.ptr(), "tile_set_light_occluder", p_id, tileset->tile_get_light_occluder(p_id)); undo_redo->add_undo_method(tileset.ptr(), "tile_set_navigation_polygon", p_id, tileset->tile_get_navigation_polygon(p_id)); } else { - Map<Vector2, Ref<OccluderPolygon2D> > oclusion_map = tileset->autotile_get_light_oclusion_map(p_id); - for (Map<Vector2, Ref<OccluderPolygon2D> >::Element *E = oclusion_map.front(); E; E = E->next()) { + Map<Vector2, Ref<OccluderPolygon2D>> oclusion_map = tileset->autotile_get_light_oclusion_map(p_id); + for (Map<Vector2, Ref<OccluderPolygon2D>>::Element *E = oclusion_map.front(); E; E = E->next()) { undo_redo->add_undo_method(tileset.ptr(), "autotile_set_light_occluder", p_id, E->value(), E->key()); } - Map<Vector2, Ref<NavigationPolygon> > navigation_map = tileset->autotile_get_navigation_map(p_id); - for (Map<Vector2, Ref<NavigationPolygon> >::Element *E = navigation_map.front(); E; E = E->next()) { + Map<Vector2, Ref<NavigationPolygon>> navigation_map = tileset->autotile_get_navigation_map(p_id); + for (Map<Vector2, Ref<NavigationPolygon>>::Element *E = navigation_map.front(); E; E = E->next()) { undo_redo->add_undo_method(tileset.ptr(), "autotile_set_navigation_polygon", p_id, E->value(), E->key()); } Map<Vector2, uint32_t> bitmask_map = tileset->autotile_get_bitmask_map(p_id); @@ -2693,8 +2693,8 @@ void TileSetEditor::draw_polygon_shapes() { } } } else { - Map<Vector2, Ref<OccluderPolygon2D> > map = tileset->autotile_get_light_oclusion_map(t_id); - for (Map<Vector2, Ref<OccluderPolygon2D> >::Element *E = map.front(); E; E = E->next()) { + Map<Vector2, Ref<OccluderPolygon2D>> map = tileset->autotile_get_light_oclusion_map(t_id); + for (Map<Vector2, Ref<OccluderPolygon2D>>::Element *E = map.front(); E; E = E->next()) { Vector2 coord = E->key(); Vector2 anchor = tileset->autotile_get_size(t_id); anchor.x += tileset->autotile_get_spacing(t_id); @@ -2781,8 +2781,8 @@ void TileSetEditor::draw_polygon_shapes() { } } } else { - Map<Vector2, Ref<NavigationPolygon> > map = tileset->autotile_get_navigation_map(t_id); - for (Map<Vector2, Ref<NavigationPolygon> >::Element *E = map.front(); E; E = E->next()) { + Map<Vector2, Ref<NavigationPolygon>> map = tileset->autotile_get_navigation_map(t_id); + for (Map<Vector2, Ref<NavigationPolygon>>::Element *E = map.front(); E; E = E->next()) { Vector2 coord = E->key(); Vector2 anchor = tileset->autotile_get_size(t_id); anchor.x += tileset->autotile_get_spacing(t_id); diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h index 7b49e2ece2..0d106ed454 100644 --- a/editor/plugins/tile_set_editor_plugin.h +++ b/editor/plugins/tile_set_editor_plugin.h @@ -114,7 +114,7 @@ class TileSetEditor : public HSplitContainer { int option; ToolButton *tileset_toolbar_buttons[TOOL_TILESET_MAX]; MenuButton *tileset_toolbar_tools; - Map<RID, Ref<Texture2D> > texture_map; + Map<RID, Ref<Texture2D>> texture_map; bool creating_shape; int dragging_point; diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 8756fe9fe9..473c1bb070 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -228,7 +228,7 @@ class VisualShaderEditor : public VBoxContainer { void _copy_nodes(); void _paste_nodes(bool p_use_custom_position = false, const Vector2 &p_custom_position = Vector2()); - Vector<Ref<VisualShaderNodePlugin> > plugins; + Vector<Ref<VisualShaderNodePlugin>> plugins; void _mode_selected(int p_id); void _rebuild(); diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 7d8a4a733d..4fb61929a3 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -2006,6 +2006,8 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { device_index_label = l; device_index = memnew(OptionButton); + device_index->set_clip_text(true); + vbc_right->add_child(device_index); setting = false; diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index f4af50eb81..6913b0253b 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -199,7 +199,7 @@ void CustomPropertyEditor::_menu_option(int p_which) { List<PropertyInfo> property_list; res_orig->get_property_list(&property_list); - List<Pair<String, Variant> > propvalues; + List<Pair<String, Variant>> propvalues; for (List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) { @@ -222,7 +222,7 @@ void CustomPropertyEditor::_menu_option(int p_which) { ERR_FAIL_COND(res.is_null()); - for (List<Pair<String, Variant> >::Element *E = propvalues.front(); E; E = E->next()) { + for (List<Pair<String, Variant>>::Element *E = propvalues.front(); E; E = E->next()) { Pair<String, Variant> &p = E->get(); res->set(p.first, p.second); @@ -270,7 +270,7 @@ void CustomPropertyEditor::_menu_option(int p_which) { int to_type = p_which - CONVERT_BASE_ID; - Vector<Ref<EditorResourceConversionPlugin> > conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(RES(v)); + Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(RES(v)); ERR_FAIL_INDEX(to_type, conversions.size()); @@ -1016,7 +1016,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: if (!RES(v).is_null()) { - Vector<Ref<EditorResourceConversionPlugin> > conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(RES(v)); + Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(RES(v)); if (conversions.size()) { menu->add_separator(); } @@ -1421,7 +1421,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) { List<PropertyInfo> property_list; res_orig->get_property_list(&property_list); - List<Pair<String, Variant> > propvalues; + List<Pair<String, Variant>> propvalues; for (List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) { @@ -1440,7 +1440,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) { ERR_FAIL_COND(res.is_null()); - for (List<Pair<String, Variant> >::Element *E = propvalues.front(); E; E = E->next()) { + for (List<Pair<String, Variant>>::Element *E = propvalues.front(); E; E = E->next()) { Pair<String, Variant> &p = E->get(); res->set(p.first, p.second); diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp index 8a5fad269f..95277e72d7 100644 --- a/editor/quick_open.cpp +++ b/editor/quick_open.cpp @@ -122,7 +122,7 @@ float EditorQuickOpen::_path_cmp(String search, String path) const { return path.to_lower().similarity(search.to_lower()); } -void EditorQuickOpen::_parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<String, Ref<Texture2D> > > &list) { +void EditorQuickOpen::_parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<String, Ref<Texture2D>>> &list) { if (!add_directories) { for (int i = 0; i < efsd->get_subdir_count(); i++) { @@ -140,7 +140,7 @@ void EditorQuickOpen::_parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<Str if (path != "res://") { path = path.substr(6, path.length()); if (search_text.is_subsequence_ofi(path)) { - Pair<String, Ref<Texture2D> > pair; + Pair<String, Ref<Texture2D>> pair; pair.first = path; pair.second = get_icon("folder", "FileDialog"); @@ -169,7 +169,7 @@ void EditorQuickOpen::_parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<Str file = file.substr(6, file.length()); if (ClassDB::is_parent_class(efsd->get_file_type(i), base_type) && (search_text.is_subsequence_ofi(file))) { - Pair<String, Ref<Texture2D> > pair; + Pair<String, Ref<Texture2D>> pair; pair.first = file; pair.second = get_icon((has_icon(efsd->get_file_type(i), ei) ? efsd->get_file_type(i) : ot), ei); list.push_back(pair); @@ -184,10 +184,10 @@ void EditorQuickOpen::_parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<Str } } -Vector<Pair<String, Ref<Texture2D> > > EditorQuickOpen::_sort_fs(Vector<Pair<String, Ref<Texture2D> > > &list) { +Vector<Pair<String, Ref<Texture2D>>> EditorQuickOpen::_sort_fs(Vector<Pair<String, Ref<Texture2D>>> &list) { String search_text = search_box->get_text(); - Vector<Pair<String, Ref<Texture2D> > > sorted_list; + Vector<Pair<String, Ref<Texture2D>>> sorted_list; if (search_text == String() || list.size() == 0) return list; @@ -223,7 +223,7 @@ void EditorQuickOpen::_update_search() { search_options->clear(); TreeItem *root = search_options->create_item(); EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->get_filesystem(); - Vector<Pair<String, Ref<Texture2D> > > list; + Vector<Pair<String, Ref<Texture2D>>> list; _parse_fs(efsd, list); list = _sort_fs(list); diff --git a/editor/quick_open.h b/editor/quick_open.h index 4814e5f310..722bad3429 100644 --- a/editor/quick_open.h +++ b/editor/quick_open.h @@ -49,8 +49,8 @@ class EditorQuickOpen : public ConfirmationDialog { void _update_search(); void _sbox_input(const Ref<InputEvent> &p_ie); - void _parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<String, Ref<Texture2D> > > &list); - Vector<Pair<String, Ref<Texture2D> > > _sort_fs(Vector<Pair<String, Ref<Texture2D> > > &list); + void _parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<String, Ref<Texture2D>>> &list); + Vector<Pair<String, Ref<Texture2D>>> _sort_fs(Vector<Pair<String, Ref<Texture2D>>> &list); float _path_cmp(String search, String path) const; void _confirmed(); diff --git a/editor/rename_dialog.h b/editor/rename_dialog.h index 2825cb2cd2..537aa1703b 100644 --- a/editor/rename_dialog.h +++ b/editor/rename_dialog.h @@ -96,7 +96,7 @@ class RenameDialog : public ConfirmationDialog { Label *lbl_preview_title; Label *lbl_preview; - List<Pair<NodePath, String> > to_rename; + List<Pair<NodePath, String>> to_rename; Node *preview_node; bool lock_preview_update; ErrorHandlerList eh; diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index c5ebf40482..7845af7f79 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -1229,7 +1229,7 @@ void SceneTreeDock::_set_owners(Node *p_owner, const Array &p_nodes) { } } -void SceneTreeDock::_fill_path_renames(Vector<StringName> base_path, Vector<StringName> new_base_path, Node *p_node, List<Pair<NodePath, NodePath> > *p_renames) { +void SceneTreeDock::_fill_path_renames(Vector<StringName> base_path, Vector<StringName> new_base_path, Node *p_node, List<Pair<NodePath, NodePath>> *p_renames) { base_path.push_back(p_node->get_name()); if (new_base_path.size()) @@ -1252,7 +1252,7 @@ void SceneTreeDock::_fill_path_renames(Vector<StringName> base_path, Vector<Stri } } -void SceneTreeDock::fill_path_renames(Node *p_node, Node *p_new_parent, List<Pair<NodePath, NodePath> > *p_renames) { +void SceneTreeDock::fill_path_renames(Node *p_node, Node *p_new_parent, List<Pair<NodePath, NodePath>> *p_renames) { if (!bool(EDITOR_DEF("editors/animation/autorename_animation_tracks", true))) return; @@ -1279,9 +1279,9 @@ void SceneTreeDock::fill_path_renames(Node *p_node, Node *p_new_parent, List<Pai _fill_path_renames(base_path, new_base_path, p_node, p_renames); } -void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodePath> > *p_renames, Map<Ref<Animation>, Set<int> > *r_rem_anims) { +void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodePath>> *p_renames, Map<Ref<Animation>, Set<int>> *r_rem_anims) { - Map<Ref<Animation>, Set<int> > rem_anims; + Map<Ref<Animation>, Set<int>> rem_anims; if (!r_rem_anims) r_rem_anims = &rem_anims; @@ -1311,7 +1311,7 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP if (p.get_type() == Variant::NODE_PATH) { // Goes through all paths to check if its matching - for (List<Pair<NodePath, NodePath> >::Element *F = p_renames->front(); F; F = F->next()) { + for (List<Pair<NodePath, NodePath>>::Element *F = p_renames->front(); F; F = F->next()) { NodePath root_path = p_base->get_path(); @@ -1353,7 +1353,7 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP NodePath root_path = root->get_path(); NodePath new_root_path = root_path; - for (List<Pair<NodePath, NodePath> >::Element *E = p_renames->front(); E; E = E->next()) { + for (List<Pair<NodePath, NodePath>>::Element *E = p_renames->front(); E; E = E->next()) { if (E->get().first == root_path) { new_root_path = E->get().second; @@ -1392,7 +1392,7 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP if (!ran.has(i)) continue; //channel was removed - for (List<Pair<NodePath, NodePath> >::Element *F = p_renames->front(); F; F = F->next()) { + for (List<Pair<NodePath, NodePath>>::Element *F = p_renames->front(); F; F = F->next()) { if (F->get().first == old_np) { @@ -1443,7 +1443,7 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP void SceneTreeDock::_node_prerenamed(Node *p_node, const String &p_new_name) { - List<Pair<NodePath, NodePath> > path_renames; + List<Pair<NodePath, NodePath>> path_renames; Vector<StringName> base_path; Node *n = p_node->get_parent(); @@ -1554,7 +1554,7 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V editor_data->get_undo_redo().create_action(TTR("Reparent Node")); - List<Pair<NodePath, NodePath> > path_renames; + List<Pair<NodePath, NodePath>> path_renames; Vector<StringName> former_names; int inc = 0; @@ -1814,7 +1814,7 @@ void SceneTreeDock::_delete_confirm() { } else { remove_list.sort_custom<Node::Comparator>(); //sort nodes to keep positions - List<Pair<NodePath, NodePath> > path_renames; + List<Pair<NodePath, NodePath>> path_renames; //delete from animation for (List<Node *>::Element *E = remove_list.front(); E; E = E->next()) { diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index c6ddbc3dfe..e41ea1ce97 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -205,7 +205,7 @@ class SceneTreeDock : public VBoxContainer { void _update_script_button(); Node *_get_selection_group_tail(Node *p_node, List<Node *> p_list); - void _fill_path_renames(Vector<StringName> base_path, Vector<StringName> new_base_path, Node *p_node, List<Pair<NodePath, NodePath> > *p_renames); + void _fill_path_renames(Vector<StringName> base_path, Vector<StringName> new_base_path, Node *p_node, List<Pair<NodePath, NodePath>> *p_renames); void _normalize_drop(Node *&to_node, int &to_pos, int p_type); @@ -249,8 +249,8 @@ public: void instance(const String &p_file); void instance_scenes(const Vector<String> &p_files, Node *p_parent = NULL); void set_selected(Node *p_node, bool p_emit_selected = false); - void fill_path_renames(Node *p_node, Node *p_new_parent, List<Pair<NodePath, NodePath> > *p_renames); - void perform_node_renames(Node *p_base, List<Pair<NodePath, NodePath> > *p_renames, Map<Ref<Animation>, Set<int> > *r_rem_anims = NULL); + void fill_path_renames(Node *p_node, Node *p_new_parent, List<Pair<NodePath, NodePath>> *p_renames); + void perform_node_renames(Node *p_base, List<Pair<NodePath, NodePath>> *p_renames, Map<Ref<Animation>, Set<int>> *r_rem_anims = NULL); SceneTreeEditor *get_tree_editor() { return scene_tree; } EditorData *get_editor_data() { return editor_data; } diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index e4e642e368..782df12d4b 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -905,7 +905,7 @@ Variant SceneTreeEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from return Variant(); //not editable tree Vector<Node *> selected; - Vector<Ref<Texture2D> > icons; + Vector<Ref<Texture2D>> icons; TreeItem *next = tree->get_next_selected(NULL); while (next) { diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index eb133abcd5..5a111afe32 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -419,7 +419,7 @@ void ScriptCreateDialog::_lang_changed(int l) { templates[i].id = new_id; } // Disable overridden - for (Map<String, Vector<int> >::Element *E = template_overrides.front(); E; E = E->next()) { + for (Map<String, Vector<int>>::Element *E = template_overrides.front(); E; E = E->next()) { const Vector<int> &overrides = E->get(); if (overrides.size() == 1) { diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h index 00f642fcf7..f73309c373 100644 --- a/editor/script_create_dialog.h +++ b/editor/script_create_dialog.h @@ -93,7 +93,7 @@ class ScriptCreateDialog : public ConfirmationDialog { String script_template; Vector<ScriptTemplateInfo> template_list; - Map<String, Vector<int> > template_overrides; // name : indices + Map<String, Vector<int>> template_overrides; // name : indices void _update_script_templates(const String &p_extension); diff --git a/editor/translations/ca.po b/editor/translations/ca.po index 15d4265ef4..304fa8905b 100644 --- a/editor/translations/ca.po +++ b/editor/translations/ca.po @@ -11,12 +11,13 @@ # Adolfo Jayme Barrientos <fitojb@ubuntu.com>, 2020. # Xavier Gomez <hiulit@gmail.com>, 2020. # Aina <ainasoga@gmail.com>, 2020. +# Alex Mancha <codingstain@gmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-02-07 10:32+0000\n" -"Last-Translator: Roger Blanco Ribera <roger.blancoribera@gmail.com>\n" +"PO-Revision-Date: 2020-03-11 12:20+0000\n" +"Last-Translator: Alex Mancha <codingstain@gmail.com>\n" "Language-Team: Catalan <https://hosted.weblate.org/projects/godot-engine/" "godot/ca/>\n" "Language: ca\n" @@ -24,7 +25,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 3.11-dev\n" +"X-Generator: Weblate 4.0-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -694,9 +695,8 @@ msgid "Line Number:" msgstr "Línia:" #: editor/code_editor.cpp -#, fuzzy msgid "%d replaced." -msgstr "Substitueix..." +msgstr "%d reemplaçat." #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d match." @@ -2756,7 +2756,6 @@ msgid "Set Up Version Control" msgstr "Configurar Control de Versions" #: editor/editor_node.cpp -#, fuzzy msgid "Shut Down Version Control" msgstr "Desactivar el control de versions" @@ -5974,7 +5973,7 @@ msgstr "" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Couldn't create a single convex collision shape." -msgstr "" +msgstr "No s'ha pogut crear una capa de col·lisió convexa." #: editor/plugins/mesh_instance_editor_plugin.cpp #, fuzzy diff --git a/editor/translations/cs.po b/editor/translations/cs.po index f3ae992410..595db1837f 100644 --- a/editor/translations/cs.po +++ b/editor/translations/cs.po @@ -22,7 +22,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-01 05:50+0000\n" +"PO-Revision-Date: 2020-03-12 23:33+0000\n" "Last-Translator: Vojtěch Šamla <auzkok@seznam.cz>\n" "Language-Team: Czech <https://hosted.weblate.org/projects/godot-engine/godot/" "cs/>\n" @@ -1117,7 +1117,7 @@ msgstr "Děkujeme za komunitu Godotu!" #: editor/editor_about.cpp msgid "Godot Engine contributors" -msgstr "Přispívající do Godot Enginu" +msgstr "Přispěvatelé do Godot Enginu" #: editor/editor_about.cpp msgid "Project Founders" @@ -9907,7 +9907,6 @@ msgid "Can't run project" msgstr "Nelze spustit projekt" #: editor/project_manager.cpp -#, fuzzy msgid "" "You currently don't have any projects.\n" "Would you like to explore official example projects in the Asset Library?" diff --git a/editor/translations/de.po b/editor/translations/de.po index 14d9926ecb..1520c3aa2a 100644 --- a/editor/translations/de.po +++ b/editor/translations/de.po @@ -53,8 +53,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-08 22:32+0000\n" -"Last-Translator: PagDev <pag.develop@gmail.com>\n" +"PO-Revision-Date: 2020-03-14 15:05+0000\n" +"Last-Translator: So Wieso <sowieso@dukun.de>\n" "Language-Team: German <https://hosted.weblate.org/projects/godot-engine/" "godot/de/>\n" "Language: de\n" @@ -6029,9 +6029,8 @@ msgstr "" "Dies ist die präziseste (aber langsamste) Methode für Kollisionsberechnungen." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Collision Sibling" -msgstr "Ein einzelnes konvexes Kollisionsunterelement erzeugen" +msgstr "Ein einzelnes konvexes Kollisionsnachbarelement erzeugen" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "" @@ -12483,7 +12482,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "ConcavePolygonShape doesn't support RigidBody in another mode than static." -msgstr "" +msgstr "ConcavePolygonShape unterstützt RigidBody nur im Modus Statisch." #: scene/3d/cpu_particles.cpp msgid "Nothing is visible because no mesh has been assigned." diff --git a/editor/translations/es.po b/editor/translations/es.po index ed82e80658..3bbe96bcb3 100644 --- a/editor/translations/es.po +++ b/editor/translations/es.po @@ -47,7 +47,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-02-27 07:01+0000\n" +"PO-Revision-Date: 2020-03-11 12:20+0000\n" "Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n" "Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/" "godot/es/>\n" @@ -6027,9 +6027,8 @@ msgstr "" "Es la opción más precisa (pero la más lenta) para la detección de colisiones." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Collision Sibling" -msgstr "Crear una Única Colisión Convexa Hermana" +msgstr "Crear Colisión Convexa Única Hermana" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "" @@ -12481,6 +12480,7 @@ msgstr "" msgid "" "ConcavePolygonShape doesn't support RigidBody in another mode than static." msgstr "" +"ConcavePolygonShape no soporta RigidBody de otro modo que no sea estático." #: scene/3d/cpu_particles.cpp msgid "Nothing is visible because no mesh has been assigned." diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po index dce0d89b7e..7781d59f34 100644 --- a/editor/translations/es_AR.po +++ b/editor/translations/es_AR.po @@ -18,7 +18,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-02-27 07:01+0000\n" +"PO-Revision-Date: 2020-03-11 12:20+0000\n" "Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n" "Language-Team: Spanish (Argentina) <https://hosted.weblate.org/projects/" "godot-engine/godot/es_AR/>\n" @@ -5991,9 +5991,8 @@ msgstr "" "Esta es la opción mas exacta (pero más lenta) de detección de colisiones." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Collision Sibling" -msgstr "Crear Colisión Convexa Unica como Nodo Hermano" +msgstr "Crear Colisión Convexa Única Hermana" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "" @@ -12435,6 +12434,7 @@ msgstr "" msgid "" "ConcavePolygonShape doesn't support RigidBody in another mode than static." msgstr "" +"ConcavePolygonShape no soporta RigidBody de otro modo que no sea estático." #: scene/3d/cpu_particles.cpp msgid "Nothing is visible because no mesh has been assigned." diff --git a/editor/translations/fi.po b/editor/translations/fi.po index d590546571..2798d56d28 100644 --- a/editor/translations/fi.po +++ b/editor/translations/fi.po @@ -14,7 +14,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-02-21 23:33+0000\n" +"PO-Revision-Date: 2020-03-14 15:05+0000\n" "Last-Translator: Tapani Niemi <tapani.niemi@kapsi.fi>\n" "Language-Team: Finnish <https://hosted.weblate.org/projects/godot-engine/" "godot/fi/>\n" @@ -23,7 +23,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 3.11.1\n" +"X-Generator: Weblate 4.0-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -5945,9 +5945,8 @@ msgstr "" "Tämä on tarkin (mutta hitain) vaihtoehto törmäystunnistukselle." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Collision Sibling" -msgstr "Luo yksittäisen konveksin törmäysmuodon sisaret" +msgstr "Luo yksittäisen konveksin törmäyksen sisar" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "" @@ -12362,6 +12361,7 @@ msgstr "" msgid "" "ConcavePolygonShape doesn't support RigidBody in another mode than static." msgstr "" +"ConcavePolygonShape ei tue RigidBody solmua muussa kuin staattisessa tilassa." #: scene/3d/cpu_particles.cpp msgid "Nothing is visible because no mesh has been assigned." diff --git a/editor/translations/ja.po b/editor/translations/ja.po index 3c14b17b53..0bb76f1261 100644 --- a/editor/translations/ja.po +++ b/editor/translations/ja.po @@ -35,7 +35,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-05 08:33+0000\n" +"PO-Revision-Date: 2020-03-16 09:43+0000\n" "Last-Translator: Akihiro Ogoshi <technical@palsystem-game.com>\n" "Language-Team: Japanese <https://hosted.weblate.org/projects/godot-engine/" "godot/ja/>\n" @@ -908,7 +908,7 @@ msgstr "切断" #: editor/connections_dialog.cpp msgid "Connect a Signal to a Method" -msgstr "メソッドにシグナルを接続する" +msgstr "メソッドにシグナルを接続" #: editor/connections_dialog.cpp msgid "Edit Connection:" @@ -5834,7 +5834,7 @@ msgstr "グラデーション編集" #: editor/plugins/item_list_editor_plugin.cpp msgid "Item %d" -msgstr "アイテム%d" +msgstr "アイテム %d" #: editor/plugins/item_list_editor_plugin.cpp msgid "Items" @@ -5854,7 +5854,7 @@ msgstr "メッシュがありません!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Couldn't create a Trimesh collision shape." -msgstr "トライメッシュコリジョンシェイプを作成できませんでした。" +msgstr "三角形メッシュ コリジョンシェイプを作成できませんでした。" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Static Trimesh Body" @@ -5954,7 +5954,7 @@ msgstr "" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Collision Sibling" -msgstr "三角形メッシュ兄弟コリジョンを生成" +msgstr "三角形メッシュ コリジョンの兄弟を作成" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "" @@ -5965,7 +5965,6 @@ msgstr "" "これは、衝突検出の最も正確な(ただし最も遅い)オプションです。" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Collision Sibling" msgstr "単一の凸型コリジョンの兄弟を作成" @@ -5979,7 +5978,7 @@ msgstr "" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Multiple Convex Collision Siblings" -msgstr "複数の凸型コリジョンの兄弟を作成する" +msgstr "複数の凸型コリジョンの兄弟を作成" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "" @@ -7654,7 +7653,7 @@ msgstr "ジオメトリが無効です。衝突ポリゴンを作成できませ #: editor/plugins/sprite_editor_plugin.cpp msgid "Create CollisionPolygon2D Sibling" -msgstr "CollisionPolygon2Dの兄弟を作成する" +msgstr "CollisionPolygon2Dの兄弟を作成" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create light occluder." @@ -7662,7 +7661,7 @@ msgstr "ジオメトリが無効です。ライトオクールダーを作成で #: editor/plugins/sprite_editor_plugin.cpp msgid "Create LightOccluder2D Sibling" -msgstr "LightOccluder2Dの兄弟を作成する" +msgstr "LightOccluder2Dの兄弟を作成" #: editor/plugins/sprite_editor_plugin.cpp msgid "Sprite" @@ -11936,9 +11935,9 @@ msgid "" " Godot Version: %s\n" "Please reinstall Android build template from 'Project' menu." msgstr "" -"Androidビルドバージョンの不一致:\n" -"インストールされたテンプレート:%s\n" -"ゴドーバージョン:%s\n" +"Androidビルド バージョンの不一致:\n" +" インストールされたテンプレート: %s\n" +" Godot バージョン: %s\n" "「プロジェクト 」メニューからAndroidビルドテンプレートを再インストールしてく" "ださい。" @@ -11952,7 +11951,7 @@ msgid "" "Alternatively visit docs.godotengine.org for Android build documentation." msgstr "" "Androidプロジェクトのビルドに失敗しました。エラーの出力を確認してください。\n" -"あるいは、Androidビルドドキュメントについてはdocs.godotengine.orgをご覧くださ" +"また、Androidビルドについてのドキュメントは docs.godotengine.org をご覧くださ" "い。" #: platform/android/export/export.cpp @@ -12372,6 +12371,8 @@ msgstr "" msgid "" "ConcavePolygonShape doesn't support RigidBody in another mode than static." msgstr "" +"ConcavePolygonShape は、Static 以外のモードの RigidBody をサポートしていませ" +"ん。" #: scene/3d/cpu_particles.cpp msgid "Nothing is visible because no mesh has been assigned." diff --git a/editor/translations/ko.po b/editor/translations/ko.po index 37c950097b..ec33599440 100644 --- a/editor/translations/ko.po +++ b/editor/translations/ko.po @@ -19,7 +19,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-05 08:33+0000\n" +"PO-Revision-Date: 2020-03-14 00:33+0000\n" "Last-Translator: Ch. <ccwpc@hanmail.net>\n" "Language-Team: Korean <https://hosted.weblate.org/projects/godot-engine/" "godot/ko/>\n" @@ -12271,6 +12271,8 @@ msgstr "" msgid "" "ConcavePolygonShape doesn't support RigidBody in another mode than static." msgstr "" +"ConcavePolygonShape는 static 외의 모드가 설정된 RigidBody를 지원하지 않습니" +"다." #: scene/3d/cpu_particles.cpp msgid "Nothing is visible because no mesh has been assigned." diff --git a/editor/translations/lv.po b/editor/translations/lv.po index dc0a5aa151..14dfdff801 100644 --- a/editor/translations/lv.po +++ b/editor/translations/lv.po @@ -4,12 +4,13 @@ # This file is distributed under the same license as the Godot source code. # Gustavs Porietis (pg829-) <porietisgustavs@gmail.com>, 2018. # Martch Zagorski <martchzagorski@gmail.com>, 2018. +# Jānis Ondzuls <janisond@inbox.lv>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2018-12-13 14:41+0100\n" -"Last-Translator: Martch Zagorski <martchzagorski@gmail.com>\n" +"PO-Revision-Date: 2020-03-11 12:20+0000\n" +"Last-Translator: Jānis Ondzuls <janisond@inbox.lv>\n" "Language-Team: Latvian <https://hosted.weblate.org/projects/godot-engine/" "godot/lv/>\n" "Language: lv\n" @@ -18,7 +19,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n % 10 == 0 || n % 100 >= 11 && n % 100 <= " "19) ? 0 : ((n % 10 == 1 && n % 100 != 11) ? 1 : 2);\n" -"X-Generator: Poedit 2.2\n" +"X-Generator: Weblate 4.0-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -65,31 +66,31 @@ msgstr "" #: core/ustring.cpp msgid "B" -msgstr "" +msgstr "B" #: core/ustring.cpp msgid "KiB" -msgstr "" +msgstr "KiB" #: core/ustring.cpp msgid "MiB" -msgstr "" +msgstr "MiB" #: core/ustring.cpp msgid "GiB" -msgstr "" +msgstr "GiB" #: core/ustring.cpp msgid "TiB" -msgstr "" +msgstr "TiB" #: core/ustring.cpp msgid "PiB" -msgstr "" +msgstr "PiB" #: core/ustring.cpp msgid "EiB" -msgstr "" +msgstr "EiB" #: editor/animation_bezier_editor.cpp msgid "Free" @@ -101,29 +102,27 @@ msgstr "Balancēts" #: editor/animation_bezier_editor.cpp msgid "Mirror" -msgstr "" +msgstr "Spogulis" #: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp msgid "Time:" -msgstr "" +msgstr "Laiks:" #: editor/animation_bezier_editor.cpp msgid "Value:" -msgstr "" +msgstr "Vērtība:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" -msgstr "" +msgstr "Ievadiet vērtību šeit" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Duplicate Selected Key(s)" -msgstr "Dublikāta Izvēle" +msgstr "Dublikāta Vērtības" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Delete Selected Key(s)" -msgstr "Izdzēst izvēlētos failus?" +msgstr "Izdzēst izvēlēto(ās) vērtību(as)?" #: editor/animation_bezier_editor.cpp msgid "Add Bezier Point" @@ -682,7 +681,7 @@ msgstr "" #: editor/array_property_edit.cpp msgid "Change Array Value" -msgstr "" +msgstr "Izmainīt masīva vērtību" #: editor/code_editor.cpp msgid "Go to Line" @@ -690,20 +689,19 @@ msgstr "Doties uz Rindu" #: editor/code_editor.cpp msgid "Line Number:" -msgstr "" +msgstr "Rindas Numurs:" #: editor/code_editor.cpp -#, fuzzy msgid "%d replaced." -msgstr "Aizvietot" +msgstr "%d aizvietots." #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d match." -msgstr "" +msgstr "%d sakritība." #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d matches." -msgstr "" +msgstr "%d sakritības." #: editor/code_editor.cpp editor/find_in_files.cpp msgid "Match Case" @@ -719,16 +717,16 @@ msgstr "Aizvietot" #: editor/code_editor.cpp msgid "Replace All" -msgstr "" +msgstr "Aizvietot visu" #: editor/code_editor.cpp msgid "Selection Only" -msgstr "" +msgstr "Tikai izvēlētais" #: editor/code_editor.cpp editor/plugins/script_text_editor.cpp #: editor/plugins/text_editor.cpp msgid "Standard" -msgstr "" +msgstr "Standarts" #: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp msgid "Toggle Scripts Panel" diff --git a/editor/translations/nl.po b/editor/translations/nl.po index 458ff0b5b8..a729ea6119 100644 --- a/editor/translations/nl.po +++ b/editor/translations/nl.po @@ -44,7 +44,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-08 22:33+0000\n" +"PO-Revision-Date: 2020-03-16 09:43+0000\n" "Last-Translator: Stijn Hinlopen <f.a.hinlopen@gmail.com>\n" "Language-Team: Dutch <https://hosted.weblate.org/projects/godot-engine/godot/" "nl/>\n" @@ -12434,7 +12434,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "ConcavePolygonShape doesn't support RigidBody in another mode than static." -msgstr "" +msgstr "ConcavePolygonShape ondersteunt RigidBody alleen in statische modus." #: scene/3d/cpu_particles.cpp msgid "Nothing is visible because no mesh has been assigned." diff --git a/editor/translations/pl.po b/editor/translations/pl.po index 14bbb799aa..de1d6d5375 100644 --- a/editor/translations/pl.po +++ b/editor/translations/pl.po @@ -42,7 +42,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-08 22:33+0000\n" +"PO-Revision-Date: 2020-03-16 09:43+0000\n" "Last-Translator: Tomek <kobewi4e@gmail.com>\n" "Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/" "godot/pl/>\n" @@ -5981,7 +5981,6 @@ msgstr "" "To jest najdokładniejsza (ale najwolniejsza) opcja do detekcji kolizji." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Collision Sibling" msgstr "Utwórz pojedynczego wypukłego sąsiada kolizji" @@ -12400,6 +12399,8 @@ msgstr "" msgid "" "ConcavePolygonShape doesn't support RigidBody in another mode than static." msgstr "" +"ConcavePolygonShape nie obsługuje węzła RigidBody w innym trybie niż " +"statyczny." #: scene/3d/cpu_particles.cpp msgid "Nothing is visible because no mesh has been assigned." diff --git a/editor/translations/pt_PT.po b/editor/translations/pt_PT.po index 60009b3171..d7532e38d4 100644 --- a/editor/translations/pt_PT.po +++ b/editor/translations/pt_PT.po @@ -19,7 +19,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-02-18 15:09+0000\n" +"PO-Revision-Date: 2020-03-16 09:43+0000\n" "Last-Translator: João Lopes <linux-man@hotmail.com>\n" "Language-Team: Portuguese (Portugal) <https://hosted.weblate.org/projects/" "godot-engine/godot/pt_PT/>\n" @@ -28,7 +28,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 3.11\n" +"X-Generator: Weblate 4.0-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -5958,7 +5958,6 @@ msgstr "" "Esta é a mais precisa (mas mais lenta) opção para deteção de colisão." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Collision Sibling" msgstr "Criar Irmãos Únicos de Colisão Convexa" @@ -12362,7 +12361,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "ConcavePolygonShape doesn't support RigidBody in another mode than static." -msgstr "" +msgstr "ConcavePolygonShape apenas suporta RigidBody no modo estático." #: scene/3d/cpu_particles.cpp msgid "Nothing is visible because no mesh has been assigned." diff --git a/editor/translations/ru.po b/editor/translations/ru.po index b05077637a..d3402fd63e 100644 --- a/editor/translations/ru.po +++ b/editor/translations/ru.po @@ -66,12 +66,13 @@ # Artur Tretiak <stikyt@protonmail.com>, 2020. # Smadjavul <o1985af@gmail.com>, 2020. # anonymous <noreply@weblate.org>, 2020. +# Vinsent Insaider_red <vinsent.in7aider@gmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-07 21:18+0000\n" -"Last-Translator: Smadjavul <o1985af@gmail.com>\n" +"PO-Revision-Date: 2020-03-11 12:20+0000\n" +"Last-Translator: Vinsent Insaider_red <vinsent.in7aider@gmail.com>\n" "Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/" "godot/ru/>\n" "Language: ru\n" @@ -98,9 +99,8 @@ msgid "Not enough bytes for decoding bytes, or invalid format." msgstr "Недостаточно байтов для декодирования байтов или неверный формат." #: core/math/expression.cpp -#, fuzzy msgid "Invalid input %i (not passed) in expression" -msgstr "Некорректный ввод %i (не был передан) в выражении" +msgstr "Некорректный ввод %i (не подходит) в выражении" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" diff --git a/editor/translations/tr.po b/editor/translations/tr.po index c73724c7b7..83eb878d8c 100644 --- a/editor/translations/tr.po +++ b/editor/translations/tr.po @@ -42,12 +42,13 @@ # Muhammet Mustafa Tozlu <m.mustafatozlu@gmail.com>, 2019. # HALİL ATAŞ <halillatass@gmail.com>, 2019. # Zsosu Ktosu <zktosu@gmail.com>, 2020. +# Mesut Aslan <kontinyu@gmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-01-30 03:56+0000\n" -"Last-Translator: Zsosu Ktosu <zktosu@gmail.com>\n" +"PO-Revision-Date: 2020-03-11 12:20+0000\n" +"Last-Translator: Mesut Aslan <kontinyu@gmail.com>\n" "Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/" "godot/tr/>\n" "Language: tr\n" @@ -55,7 +56,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 3.11-dev\n" +"X-Generator: Weblate 4.0-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -726,9 +727,8 @@ msgid "Line Number:" msgstr "Satır Numarası:" #: editor/code_editor.cpp -#, fuzzy msgid "%d replaced." -msgstr "Değiştir..." +msgstr "%d değiştirildi." #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d match." @@ -3989,9 +3989,8 @@ msgid "Saving..." msgstr "Kaydediliyor..." #: editor/import_dock.cpp -#, fuzzy msgid "%d Files" -msgstr " Dosyalar" +msgstr "%d Dosya" #: editor/import_dock.cpp msgid "Set as Default for '%s'" @@ -5870,9 +5869,8 @@ msgid "Mesh is empty!" msgstr "Örüntü boş!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Couldn't create a Trimesh collision shape." -msgstr "Üçlü Örüntü Çarpışma Kardeşi Oluştur" +msgstr "Trimesh çarpışma şekli oluşturulamadı." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Static Trimesh Body" @@ -5888,25 +5886,23 @@ msgstr "Üçlü Örüntü Yüzeyi Oluştur" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Can't create a single convex collision shape for the scene root." -msgstr "" +msgstr "Sahne kökü için tek bir dışbükey çarpışma şekli oluşturulamaz." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Couldn't create a single convex collision shape." -msgstr "" +msgstr "Tek dışbükey çarpışma şekli oluşturulamadı." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Shape" -msgstr "Dışbükey Şekil[ler] Oluştur" +msgstr "Tekil Dışbükey Şekil Oluştur" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Can't create multiple convex collision shapes for the scene root." msgstr "" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Couldn't create any collision shapes." -msgstr "Klasör oluşturulamadı." +msgstr "Herhangi bir çarpışma şekli oluşturulamadı." #: editor/plugins/mesh_instance_editor_plugin.cpp #, fuzzy @@ -5977,6 +5973,8 @@ msgid "" "Creates a polygon-based collision shape.\n" "This is the most accurate (but slowest) option for collision detection." msgstr "" +"Poligon bazlı bir çarpışma şekli oluştur.\n" +"Bu en hassas (fakat en yavaş) çarpışma algılama seçeneğidir." #: editor/plugins/mesh_instance_editor_plugin.cpp #, fuzzy diff --git a/main/input_default.h b/main/input_default.h index 549093955d..0ec31d417b 100644 --- a/main/input_default.h +++ b/main/input_default.h @@ -183,7 +183,7 @@ private: void _parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated); - List<Ref<InputEvent> > accumulated_events; + List<Ref<InputEvent>> accumulated_events; bool use_accumulated_input; public: diff --git a/main/tests/test_ordered_hash_map.cpp b/main/tests/test_ordered_hash_map.cpp index 4a74ad5898..cc779119bc 100644 --- a/main/tests/test_ordered_hash_map.cpp +++ b/main/tests/test_ordered_hash_map.cpp @@ -84,7 +84,7 @@ bool test_iteration() { map.insert(123485, 1238888); map.insert(123, 111111); - Vector<Pair<int, int> > expected; + Vector<Pair<int, int>> expected; expected.push_back(Pair<int, int>(42, 84)); expected.push_back(Pair<int, int>(123, 111111)); expected.push_back(Pair<int, int>(0, 12934)); @@ -101,7 +101,7 @@ bool test_iteration() { } bool test_const_iteration(const OrderedHashMap<int, int> &map) { - Vector<Pair<int, int> > expected; + Vector<Pair<int, int>> expected; expected.push_back(Pair<int, int>(42, 84)); expected.push_back(Pair<int, int>(123, 111111)); expected.push_back(Pair<int, int>(0, 12934)); diff --git a/main/tests/test_physics.cpp b/main/tests/test_physics.cpp index 0304e8f6dd..4931d42674 100644 --- a/main/tests/test_physics.cpp +++ b/main/tests/test_physics.cpp @@ -222,7 +222,7 @@ protected: void make_grid(int p_width, int p_height, float p_cellsize, float p_cellheight, const Transform &p_xform = Transform()) { - Vector<Vector<float> > grid; + Vector<Vector<float>> grid; grid.resize(p_width); diff --git a/modules/assimp/editor_scene_importer_assimp.cpp b/modules/assimp/editor_scene_importer_assimp.cpp index 1881d0db33..682a7e33c8 100644 --- a/modules/assimp/editor_scene_importer_assimp.cpp +++ b/modules/assimp/editor_scene_importer_assimp.cpp @@ -872,7 +872,7 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat const unsigned int mesh_idx = p_surface_indices[i]; const aiMesh *ai_mesh = state.assimp_scene->mMeshes[mesh_idx]; - Map<uint32_t, Vector<BoneInfo> > vertex_weights; + Map<uint32_t, Vector<BoneInfo>> vertex_weights; if (ai_mesh->mNumBones > 0) { for (size_t b = 0; b < ai_mesh->mNumBones; b++) { diff --git a/modules/assimp/import_state.h b/modules/assimp/import_state.h index 26aad423cd..fbbbe23399 100644 --- a/modules/assimp/import_state.h +++ b/modules/assimp/import_state.h @@ -61,15 +61,15 @@ struct ImportState { const aiScene *assimp_scene; uint32_t max_bone_weights; - Map<String, Ref<Mesh> > mesh_cache; - Map<int, Ref<Material> > material_cache; + Map<String, Ref<Mesh>> mesh_cache; + Map<int, Ref<Material>> material_cache; Map<String, int> light_cache; Map<String, int> camera_cache; // very useful for when you need to ask assimp for the bone mesh Map<const aiNode *, Node *> assimp_node_map; - Map<String, Ref<Image> > path_to_image_cache; + Map<String, Ref<Image>> path_to_image_cache; // Generation 3 - determinisitic iteration // to lower potential recursion errors diff --git a/modules/assimp/import_utils.h b/modules/assimp/import_utils.h index 80b67b5453..30c00f8765 100644 --- a/modules/assimp/import_utils.h +++ b/modules/assimp/import_utils.h @@ -341,7 +341,7 @@ public: */ static Ref<Image> load_image(ImportState &state, const aiScene *p_scene, String p_path) { - Map<String, Ref<Image> >::Element *match = state.path_to_image_cache.find(p_path); + Map<String, Ref<Image>>::Element *match = state.path_to_image_cache.find(p_path); // if our cache contains this image then don't bother if (match) { diff --git a/modules/basis_universal/SCsub b/modules/basis_universal/SCsub index d7342358d7..63324e920b 100644 --- a/modules/basis_universal/SCsub +++ b/modules/basis_universal/SCsub @@ -22,7 +22,6 @@ tool_sources = [ "basisu_resample_filters.cpp", "basisu_resampler.cpp", "basisu_ssim.cpp", - "basisu_tool.cpp", "lodepng.cpp", ] tool_sources = [thirdparty_dir + file for file in tool_sources] diff --git a/modules/bullet/soft_body_bullet.h b/modules/bullet/soft_body_bullet.h index 2df8ce074f..05d7e6ce3f 100644 --- a/modules/bullet/soft_body_bullet.h +++ b/modules/bullet/soft_body_bullet.h @@ -59,7 +59,7 @@ class SoftBodyBullet : public CollisionObjectBullet { private: btSoftBody *bt_soft_body; - Vector<Vector<int> > indices_table; + Vector<Vector<int>> indices_table; btSoftBody::Material *mat0; // This is just a copy of pointer managed by btSoftBody bool isScratched; diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp index e9ca1d3e5b..3f61e2852f 100644 --- a/modules/csg/csg.cpp +++ b/modules/csg/csg.cpp @@ -88,7 +88,7 @@ static inline bool ray_intersects_triangle(const Vector3 &p_from, const Vector3 Vector3 edge2 = p_vertices[2] - p_vertices[0]; Vector3 h = p_dir.cross(edge2); real_t a = edge1.dot(h); - // Check if ray is parrallel to triangle. + // Check if ray is parallel to triangle. if (Math::is_zero_approx(a)) return false; real_t f = 1.0 / a; @@ -179,7 +179,7 @@ void CSGBrush::_regen_face_aabbs() { } } -void CSGBrush::build_from_faces(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uvs, const Vector<bool> &p_smooth, const Vector<Ref<Material> > &p_materials, const Vector<bool> &p_invert_faces) { +void CSGBrush::build_from_faces(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uvs, const Vector<bool> &p_smooth, const Vector<Ref<Material>> &p_materials, const Vector<bool> &p_invert_faces) { faces.clear(); @@ -818,7 +818,7 @@ void CSGBrushOperation::Build2DFaces::_add_vertex_idx_sorted(Vector<int> &r_vert int axis = 0; if (Math::abs(new_point.x - first_point.x) < Math::abs(new_point.y - first_point.y)) axis = 1; - // Add it to the beginnig or the end appropriately. + // Add it to the beginning or the end appropriately. if (new_point[axis] < first_point[axis]) r_vertex_indices.insert(0, p_new_vertex_index); else @@ -868,7 +868,7 @@ void CSGBrushOperation::Build2DFaces::_merge_faces(const Vector<int> &p_segment_ inner_idx = p_segment_indices[segments + segments / 2 - sorted_idx]; } - // Find the mergable faces. + // Find the mergeable faces. Vector<int> merge_faces_idx; Vector<Face2D> merge_faces; Vector<int> merge_faces_inner_vertex_idx; diff --git a/modules/csg/csg.h b/modules/csg/csg.h index bb83c84cb5..d389cbc283 100644 --- a/modules/csg/csg.h +++ b/modules/csg/csg.h @@ -55,12 +55,12 @@ struct CSGBrush { }; Vector<Face> faces; - Vector<Ref<Material> > materials; + Vector<Ref<Material>> materials; inline void _regen_face_aabbs(); // Create a brush from faces. - void build_from_faces(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uvs, const Vector<bool> &p_smooth, const Vector<Ref<Material> > &p_materials, const Vector<bool> &p_invert_faces); + void build_from_faces(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uvs, const Vector<bool> &p_smooth, const Vector<Ref<Material>> &p_materials, const Vector<bool> &p_invert_faces); void copy_from(const CSGBrush &p_brush, const Transform &p_xform); }; diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index a227d49892..54635ae320 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -665,7 +665,7 @@ CSGCombiner::CSGCombiner() { ///////////////////// -CSGBrush *CSGPrimitive::_create_brush_from_arrays(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uv, const Vector<bool> &p_smooth, const Vector<Ref<Material> > &p_materials) { +CSGBrush *CSGPrimitive::_create_brush_from_arrays(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uv, const Vector<bool> &p_smooth, const Vector<Ref<Material>> &p_materials) { CSGBrush *brush = memnew(CSGBrush); @@ -717,7 +717,7 @@ CSGBrush *CSGMesh::_build_brush() { Vector<Vector3> vertices; Vector<bool> smooth; - Vector<Ref<Material> > materials; + Vector<Ref<Material>> materials; Vector<Vector2> uvs; Ref<Material> material = get_material(); @@ -927,7 +927,7 @@ CSGBrush *CSGSphere::_build_brush() { Vector<Vector3> faces; Vector<Vector2> uvs; Vector<bool> smooth; - Vector<Ref<Material> > materials; + Vector<Ref<Material>> materials; Vector<bool> invert; faces.resize(face_count * 3); @@ -1130,7 +1130,7 @@ CSGBrush *CSGBox::_build_brush() { Vector<Vector3> faces; Vector<Vector2> uvs; Vector<bool> smooth; - Vector<Ref<Material> > materials; + Vector<Ref<Material>> materials; Vector<bool> invert; faces.resize(face_count * 3); @@ -1308,7 +1308,7 @@ CSGBrush *CSGCylinder::_build_brush() { Vector<Vector3> faces; Vector<Vector2> uvs; Vector<bool> smooth; - Vector<Ref<Material> > materials; + Vector<Ref<Material>> materials; Vector<bool> invert; faces.resize(face_count * 3); @@ -1557,7 +1557,7 @@ CSGBrush *CSGTorus::_build_brush() { Vector<Vector3> faces; Vector<Vector2> uvs; Vector<bool> smooth; - Vector<Ref<Material> > materials; + Vector<Ref<Material>> materials; Vector<bool> invert; faces.resize(face_count * 3); @@ -1851,7 +1851,7 @@ CSGBrush *CSGPolygon::_build_brush() { Vector<Vector3> faces; Vector<Vector2> uvs; Vector<bool> smooth; - Vector<Ref<Material> > materials; + Vector<Ref<Material>> materials; Vector<bool> invert; faces.resize(face_count * 3); diff --git a/modules/csg/csg_shape.h b/modules/csg/csg_shape.h index 909437e39b..fdbf979fe7 100644 --- a/modules/csg/csg_shape.h +++ b/modules/csg/csg_shape.h @@ -172,7 +172,7 @@ private: bool invert_faces; protected: - CSGBrush *_create_brush_from_arrays(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uv, const Vector<bool> &p_smooth, const Vector<Ref<Material> > &p_materials); + CSGBrush *_create_brush_from_arrays(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uv, const Vector<bool> &p_smooth, const Vector<Ref<Material>> &p_materials); static void _bind_methods(); public: diff --git a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml index 456bf649d2..860da32a22 100644 --- a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml +++ b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml @@ -134,7 +134,7 @@ The compression method used for network packets. These have different tradeoffs of compression speed versus bandwidth, you may need to test which one works best for your use case if you use compression at all. </member> <member name="dtls_verify" type="bool" setter="set_dtls_verify_enabled" getter="is_dtls_verify_enabled" default="true"> - Enable or disable certiticate verification when [member use_dtls] [code]true[/code]. + Enable or disable certificate verification when [member use_dtls] [code]true[/code]. </member> <member name="refuse_new_connections" type="bool" setter="set_refuse_new_connections" getter="is_refusing_new_connections" override="true" default="false" /> <member name="server_relay" type="bool" setter="set_server_relay_enabled" getter="is_server_relay_enabled" default="true"> diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index 33b734f672..0457a42f30 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -48,7 +48,7 @@ static const bool default_reloadable = true; // Defined in gdnative_api_struct.gen.cpp extern const godot_gdnative_core_api_struct api_struct; -Map<String, Vector<Ref<GDNative> > > GDNativeLibrary::loaded_libraries; +Map<String, Vector<Ref<GDNative>>> GDNativeLibrary::loaded_libraries; GDNativeLibrary::GDNativeLibrary() { config_file.instance(); @@ -373,7 +373,7 @@ bool GDNative::initialize() { initialized = true; if (library->should_load_once() && !GDNativeLibrary::loaded_libraries.has(lib_path)) { - Vector<Ref<GDNative> > gdnatives; + Vector<Ref<GDNative>> gdnatives; gdnatives.resize(1); gdnatives.write[0] = Ref<GDNative>(this); GDNativeLibrary::loaded_libraries.insert(lib_path, gdnatives); @@ -390,7 +390,7 @@ bool GDNative::terminate() { } if (library->should_load_once()) { - Vector<Ref<GDNative> > *gdnatives = &GDNativeLibrary::loaded_libraries[library->get_current_library_path()]; + Vector<Ref<GDNative>> *gdnatives = &GDNativeLibrary::loaded_libraries[library->get_current_library_path()]; if (gdnatives->size() > 1) { // there are other GDNative's still using this library, so we actually don't terminate gdnatives->erase(Ref<GDNative>(this)); diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index b4c5ec9d00..9ef9c706d1 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -47,7 +47,7 @@ class GDNative; class GDNativeLibrary : public Resource { GDCLASS(GDNativeLibrary, Resource); - static Map<String, Vector<Ref<GDNative> > > loaded_libraries; + static Map<String, Vector<Ref<GDNative>>> loaded_libraries; friend class GDNativeLibraryResourceLoader; friend class GDNative; diff --git a/modules/gdnative/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp index 850871579b..11fe746e90 100644 --- a/modules/gdnative/nativescript/api_generator.cpp +++ b/modules/gdnative/nativescript/api_generator.cpp @@ -98,7 +98,7 @@ struct SignalAPI { struct EnumAPI { String name; - List<Pair<int, String> > values; + List<Pair<int, String>> values; }; struct ClassAPI { @@ -395,7 +395,7 @@ List<ClassAPI> generate_c_api_classes() { int int_val = ClassDB::get_integer_constant(class_name, val_e->get(), NULL); enum_api.values.push_back(Pair<int, String>(int_val, val_e->get())); } - enum_api.values.sort_custom<PairSort<int, String> >(); + enum_api.values.sort_custom<PairSort<int, String>>(); class_api.enums.push_back(enum_api); } } @@ -497,7 +497,7 @@ static List<String> generate_c_api_json(const List<ClassAPI> &p_api) { source.push_back("\t\t\t{\n"); source.push_back("\t\t\t\t\"name\": \"" + e->get().name + "\",\n"); source.push_back("\t\t\t\t\"values\": {\n"); - for (List<Pair<int, String> >::Element *val_e = e->get().values.front(); val_e; val_e = val_e->next()) { + for (List<Pair<int, String>>::Element *val_e = e->get().values.front(); val_e; val_e = val_e->next()) { source.push_back("\t\t\t\t\t\"" + val_e->get().second + "\": " + itos(val_e->get().first)); source.push_back(String((val_e->next() ? "," : "")) + "\n"); } diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index d0e196b3e6..fb88479ca3 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -1139,16 +1139,16 @@ NativeScriptLanguage *NativeScriptLanguage::singleton; void NativeScriptLanguage::_unload_stuff(bool p_reload) { - Map<String, Ref<GDNative> > erase_and_unload; + Map<String, Ref<GDNative>> erase_and_unload; - for (Map<String, Map<StringName, NativeScriptDesc> >::Element *L = library_classes.front(); L; L = L->next()) { + for (Map<String, Map<StringName, NativeScriptDesc>>::Element *L = library_classes.front(); L; L = L->next()) { String lib_path = L->key(); Map<StringName, NativeScriptDesc> classes = L->get(); if (p_reload) { - Map<String, Ref<GDNative> >::Element *E = library_gdnatives.find(lib_path); + Map<String, Ref<GDNative>>::Element *E = library_gdnatives.find(lib_path); Ref<GDNative> gdn; if (E) { @@ -1169,7 +1169,7 @@ void NativeScriptLanguage::_unload_stuff(bool p_reload) { } } - Map<String, Ref<GDNative> >::Element *E = library_gdnatives.find(lib_path); + Map<String, Ref<GDNative>>::Element *E = library_gdnatives.find(lib_path); Ref<GDNative> gdn; if (E) { @@ -1204,7 +1204,7 @@ void NativeScriptLanguage::_unload_stuff(bool p_reload) { erase_and_unload.insert(lib_path, gdn); } - for (Map<String, Ref<GDNative> >::Element *E = erase_and_unload.front(); E; E = E->next()) { + for (Map<String, Ref<GDNative>>::Element *E = erase_and_unload.front(); E; E = E->next()) { String lib_path = E->key(); Ref<GDNative> gdn = E->get(); @@ -1247,7 +1247,7 @@ NativeScriptLanguage::NativeScriptLanguage() { NativeScriptLanguage::~NativeScriptLanguage() { - for (Map<String, Ref<GDNative> >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) { + for (Map<String, Ref<GDNative>>::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) { Ref<GDNative> lib = L->get(); // only shut down valid libs, duh! @@ -1385,7 +1385,7 @@ void NativeScriptLanguage::get_recognized_extensions(List<String> *p_extensions) void NativeScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const { } -void NativeScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_constants) const { +void NativeScriptLanguage::get_public_constants(List<Pair<String, Variant>> *p_constants) const { } void NativeScriptLanguage::profiling_start() { @@ -1679,7 +1679,7 @@ void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) { // See if this library was "registered" already. const String &lib_path = lib->get_current_library_path(); ERR_FAIL_COND_MSG(lib_path.length() == 0, lib->get_name() + " does not have a library for the current platform."); - Map<String, Ref<GDNative> >::Element *E = library_gdnatives.find(lib_path); + Map<String, Ref<GDNative>>::Element *E = library_gdnatives.find(lib_path); if (!E) { Ref<GDNative> gdn; @@ -1719,7 +1719,7 @@ void NativeScriptLanguage::register_script(NativeScript *script) { void NativeScriptLanguage::unregister_script(NativeScript *script) { MutexLock lock(mutex); - Map<String, Set<NativeScript *> >::Element *S = library_script_users.find(script->lib_path); + Map<String, Set<NativeScript *>>::Element *S = library_script_users.find(script->lib_path); if (S) { S->get().erase(script); if (S->get().size() == 0) { @@ -1733,7 +1733,7 @@ void NativeScriptLanguage::unregister_script(NativeScript *script) { void NativeScriptLanguage::call_libraries_cb(const StringName &name) { // library_gdnatives is modified only from the main thread, so it's safe not to use mutex here - for (Map<String, Ref<GDNative> >::Element *L = library_gdnatives.front(); L; L = L->next()) { + for (Map<String, Ref<GDNative>>::Element *L = library_gdnatives.front(); L; L = L->next()) { if (L->get().is_null()) { continue; @@ -1755,7 +1755,7 @@ void NativeScriptLanguage::frame() { #ifndef NO_THREADS if (has_objects_to_register) { MutexLock lock(mutex); - for (Set<Ref<GDNativeLibrary> >::Element *L = libs_to_init.front(); L; L = L->next()) { + for (Set<Ref<GDNativeLibrary>>::Element *L = libs_to_init.front(); L; L = L->next()) { init_library(L->get()); } libs_to_init.clear(); @@ -1834,7 +1834,7 @@ void NativeReloadNode::_notification(int p_what) { MutexLock lock(NSL->mutex); NSL->_unload_stuff(true); - for (Map<String, Ref<GDNative> >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) { + for (Map<String, Ref<GDNative>>::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) { Ref<GDNative> gdn = L->get(); @@ -1869,7 +1869,7 @@ void NativeReloadNode::_notification(int p_what) { MutexLock lock(NSL->mutex); Set<StringName> libs_to_remove; - for (Map<String, Ref<GDNative> >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) { + for (Map<String, Ref<GDNative>>::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) { Ref<GDNative> gdn = L->get(); @@ -1904,7 +1904,7 @@ void NativeReloadNode::_notification(int p_what) { ((void (*)(void *))proc_ptr)((void *)&L->key()); } - for (Map<String, Set<NativeScript *> >::Element *U = NSL->library_script_users.front(); U; U = U->next()) { + for (Map<String, Set<NativeScript *>>::Element *U = NSL->library_script_users.front(); U; U = U->next()) { for (Set<NativeScript *>::Element *S = U->get().front(); S; S = S->next()) { NativeScript *script = S->get(); diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index 90542c96b7..aba3f6b2d0 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -263,7 +263,7 @@ private: Mutex mutex; #ifndef NO_THREADS - Set<Ref<GDNativeLibrary> > libs_to_init; + Set<Ref<GDNativeLibrary>> libs_to_init; Set<NativeScript *> scripts_to_register; volatile bool has_objects_to_register; // so that we don't lock mutex every frame - it's rarely needed void defer_init_library(Ref<GDNativeLibrary> lib, NativeScript *script); @@ -275,10 +275,10 @@ private: void call_libraries_cb(const StringName &name); - Vector<Pair<bool, godot_instance_binding_functions> > binding_functions; + Vector<Pair<bool, godot_instance_binding_functions>> binding_functions; Set<Vector<void *> *> binding_instances; - Map<int, HashMap<StringName, const void *> > global_type_tags; + Map<int, HashMap<StringName, const void *>> global_type_tags; struct ProfileData { StringName signature; @@ -298,10 +298,10 @@ private: public: // These two maps must only be touched on the main thread - Map<String, Map<StringName, NativeScriptDesc> > library_classes; - Map<String, Ref<GDNative> > library_gdnatives; + Map<String, Map<StringName, NativeScriptDesc>> library_classes; + Map<String, Ref<GDNative>> library_gdnatives; - Map<String, Set<NativeScript *> > library_script_users; + Map<String, Set<NativeScript *>> library_script_users; StringName _init_call_type; StringName _init_call_name; @@ -362,7 +362,7 @@ public: virtual void reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual void get_public_functions(List<MethodInfo> *p_functions) const; - virtual void get_public_constants(List<Pair<String, Variant> > *p_constants) const; + virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const; virtual void profiling_start(); virtual void profiling_stop(); virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max); diff --git a/modules/gdnative/pluginscript/pluginscript_language.cpp b/modules/gdnative/pluginscript/pluginscript_language.cpp index a40b59bb2e..bccbe95033 100644 --- a/modules/gdnative/pluginscript/pluginscript_language.cpp +++ b/modules/gdnative/pluginscript/pluginscript_language.cpp @@ -210,7 +210,7 @@ void PluginScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) c } } -void PluginScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_constants) const { +void PluginScriptLanguage::get_public_constants(List<Pair<String, Variant>> *p_constants) const { // TODO: provide this statically in `godot_pluginscript_language_desc` ? if (_desc.get_public_constants) { Dictionary constants; diff --git a/modules/gdnative/pluginscript/pluginscript_language.h b/modules/gdnative/pluginscript/pluginscript_language.h index 3f0d2b8d3d..809034744a 100644 --- a/modules/gdnative/pluginscript/pluginscript_language.h +++ b/modules/gdnative/pluginscript/pluginscript_language.h @@ -112,7 +112,7 @@ public: virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual void get_public_functions(List<MethodInfo> *p_functions) const; - virtual void get_public_constants(List<Pair<String, Variant> > *p_constants) const; + virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const; virtual void profiling_start(); virtual void profiling_stop(); diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp index e5d688afd4..397a020689 100644 --- a/modules/gdnative/register_types.cpp +++ b/modules/gdnative/register_types.cpp @@ -214,7 +214,7 @@ static godot_variant cb_standard_varcall(void *p_procedure_handle, godot_array * GDNativeCallRegistry *GDNativeCallRegistry::singleton; -Vector<Ref<GDNative> > singleton_gdnatives; +Vector<Ref<GDNative>> singleton_gdnatives; Ref<GDNativeLibraryResourceLoader> resource_loader_gdnlib; Ref<GDNativeLibraryResourceSaver> resource_saver_gdnlib; diff --git a/modules/gdnavigation/gd_navigation_server.cpp b/modules/gdnavigation/gd_navigation_server.cpp index 4db10cda78..a1f6ddfedc 100644 --- a/modules/gdnavigation/gd_navigation_server.cpp +++ b/modules/gdnavigation/gd_navigation_server.cpp @@ -41,7 +41,7 @@ */ /// Creates a struct for each function and a function that once called creates -/// an instance of that struct with the submited parameters. +/// an instance of that struct with the submitted parameters. /// Then, that struct is stored in an array; the `sync` function consume that array. #define COMMAND_1(F_NAME, T_0, D_0) \ diff --git a/modules/gdnavigation/nav_map.cpp b/modules/gdnavigation/nav_map.cpp index 00a1901c48..338e49eb9f 100644 --- a/modules/gdnavigation/nav_map.cpp +++ b/modules/gdnavigation/nav_map.cpp @@ -691,7 +691,7 @@ void NavMap::sync() { const float ecm_squared(edge_connection_margin * edge_connection_margin); #define LEN_TOLLERANCE 0.1 #define DIR_TOLLERANCE 0.9 - // In front of tollerance + // In front of tolerance #define IFO_TOLLERANCE 0.5 // Find the compatible near edges. @@ -715,7 +715,7 @@ void NavMap::sync() { Vector3 rel_centers = other_edge.edge_center - edge.edge_center; if (ecm_squared > rel_centers.length_squared() // Are enough closer? && ABS(edge.edge_len_squared - other_edge.edge_len_squared) < LEN_TOLLERANCE // Are the same length? - && ABS(edge.edge_dir.dot(other_edge.edge_dir)) > DIR_TOLLERANCE // Are alligned? + && ABS(edge.edge_dir.dot(other_edge.edge_dir)) > DIR_TOLLERANCE // Are aligned? && ABS(rel_centers.normalized().dot(edge.edge_dir)) < IFO_TOLLERANCE // Are one in front the other? ) { // The edges can be connected diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index d31823d632..05e9f8652e 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -522,7 +522,7 @@ void GDScript::update_exports() { void GDScript::_set_subclass_path(Ref<GDScript> &p_sc, const String &p_path) { p_sc->path = p_path; - for (Map<StringName, Ref<GDScript> >::Element *E = p_sc->subclasses.front(); E; E = E->next()) { + for (Map<StringName, Ref<GDScript>>::Element *E = p_sc->subclasses.front(); E; E = E->next()) { _set_subclass_path(E->get(), p_path); } @@ -592,57 +592,12 @@ Error GDScript::reload(bool p_keep_state) { valid = true; - for (Map<StringName, Ref<GDScript> >::Element *E = subclasses.front(); E; E = E->next()) { + for (Map<StringName, Ref<GDScript>>::Element *E = subclasses.front(); E; E = E->next()) { _set_subclass_path(E->get(), path); } - // Copy the base rpc methods so we don't mask their IDs. - rpc_functions.clear(); - rpc_variables.clear(); - if (base.is_valid()) { - rpc_functions = base->rpc_functions; - rpc_variables = base->rpc_variables; - } - - GDScript *cscript = this; - Map<StringName, Ref<GDScript> >::Element *sub_E = subclasses.front(); - while (cscript) { - // RPC Methods - for (Map<StringName, GDScriptFunction *>::Element *E = cscript->member_functions.front(); E; E = E->next()) { - if (E->get()->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) { - ScriptNetData nd; - nd.name = E->key(); - nd.mode = E->get()->get_rpc_mode(); - if (-1 == rpc_functions.find(nd)) { - rpc_functions.push_back(nd); - } - } - } - // RSet - for (Map<StringName, MemberInfo>::Element *E = cscript->member_indices.front(); E; E = E->next()) { - if (E->get().rpc_mode != MultiplayerAPI::RPC_MODE_DISABLED) { - ScriptNetData nd; - nd.name = E->key(); - nd.mode = E->get().rpc_mode; - if (-1 == rpc_variables.find(nd)) { - rpc_variables.push_back(nd); - } - } - } - - if (cscript != this) - sub_E = sub_E->next(); - - if (sub_E) - cscript = sub_E->get().ptr(); - else - cscript = NULL; - } - - // Sort so we are 100% that they are always the same. - rpc_functions.sort_custom<SortNetData>(); - rpc_variables.sort_custom<SortNetData>(); + _init_rpc_methods_properties(); return OK; } @@ -715,8 +670,8 @@ StringName GDScript::get_rset_property(const uint16_t p_rset_member_id) const { } MultiplayerAPI::RPCMode GDScript::get_rset_mode_by_id(const uint16_t p_rset_member_id) const { - ERR_FAIL_COND_V(p_rset_member_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED); - return rpc_functions[p_rset_member_id].mode; + ERR_FAIL_COND_V(p_rset_member_id >= rpc_variables.size(), MultiplayerAPI::RPC_MODE_DISABLED); + return rpc_variables[p_rset_member_id].mode; } MultiplayerAPI::RPCMode GDScript::get_rset_mode(const StringName &p_variable) const { @@ -760,7 +715,7 @@ bool GDScript::_get(const StringName &p_name, Variant &r_ret) const { } { - const Map<StringName, Ref<GDScript> >::Element *E = subclasses.find(p_name); + const Map<StringName, Ref<GDScript>>::Element *E = subclasses.find(p_name); if (E) { r_ret = E->get(); @@ -876,11 +831,13 @@ Error GDScript::load_byte_code(const String &p_path) { valid = true; - for (Map<StringName, Ref<GDScript> >::Element *E = subclasses.front(); E; E = E->next()) { + for (Map<StringName, Ref<GDScript>>::Element *E = subclasses.front(); E; E = E->next()) { _set_subclass_path(E->get(), path); } + _init_rpc_methods_properties(); + return OK; } @@ -953,7 +910,7 @@ bool GDScript::has_script_signal(const StringName &p_signal) const { } void GDScript::get_script_signal_list(List<MethodInfo> *r_signals) const { - for (const Map<StringName, Vector<StringName> >::Element *E = _signals.front(); E; E = E->next()) { + for (const Map<StringName, Vector<StringName>>::Element *E = _signals.front(); E; E = E->next()) { MethodInfo mi; mi.name = E->key(); @@ -1006,7 +963,7 @@ void GDScript::_save_orphaned_subclasses() { }; Vector<ClassRefWithName> weak_subclasses; // collect subclasses ObjectID and name - for (Map<StringName, Ref<GDScript> >::Element *E = subclasses.front(); E; E = E->next()) { + for (Map<StringName, Ref<GDScript>>::Element *E = subclasses.front(); E; E = E->next()) { E->get()->_owner = NULL; //bye, you are no longer owned cause I died ClassRefWithName subclass; subclass.id = E->get()->get_instance_id(); @@ -1030,6 +987,55 @@ void GDScript::_save_orphaned_subclasses() { } } +void GDScript::_init_rpc_methods_properties() { + // Copy the base rpc methods so we don't mask their IDs. + rpc_functions.clear(); + rpc_variables.clear(); + if (base.is_valid()) { + rpc_functions = base->rpc_functions; + rpc_variables = base->rpc_variables; + } + + GDScript *cscript = this; + Map<StringName, Ref<GDScript>>::Element *sub_E = subclasses.front(); + while (cscript) { + // RPC Methods + for (Map<StringName, GDScriptFunction *>::Element *E = cscript->member_functions.front(); E; E = E->next()) { + if (E->get()->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) { + ScriptNetData nd; + nd.name = E->key(); + nd.mode = E->get()->get_rpc_mode(); + if (-1 == rpc_functions.find(nd)) { + rpc_functions.push_back(nd); + } + } + } + // RSet + for (Map<StringName, MemberInfo>::Element *E = cscript->member_indices.front(); E; E = E->next()) { + if (E->get().rpc_mode != MultiplayerAPI::RPC_MODE_DISABLED) { + ScriptNetData nd; + nd.name = E->key(); + nd.mode = E->get().rpc_mode; + if (-1 == rpc_variables.find(nd)) { + rpc_variables.push_back(nd); + } + } + } + + if (cscript != this) + sub_E = sub_E->next(); + + if (sub_E) + cscript = sub_E->get().ptr(); + else + cscript = NULL; + } + + // Sort so we are 100% that they are always the same. + rpc_functions.sort_custom<SortNetData>(); + rpc_variables.sort_custom<SortNetData>(); +} + GDScript::~GDScript() { for (Map<StringName, GDScriptFunction *>::Element *E = member_functions.front(); E; E = E->next()) { memdelete(E->get()); @@ -1655,7 +1661,7 @@ void GDScriptLanguage::reload_all_scripts() { #ifdef DEBUG_ENABLED print_verbose("GDScript: Reloading all scripts"); - List<Ref<GDScript> > scripts; + List<Ref<GDScript>> scripts; { MutexLock lock(this->lock); @@ -1673,7 +1679,7 @@ void GDScriptLanguage::reload_all_scripts() { scripts.sort_custom<GDScriptDepSort>(); //update in inheritance dependency order - for (List<Ref<GDScript> >::Element *E = scripts.front(); E; E = E->next()) { + for (List<Ref<GDScript>>::Element *E = scripts.front(); E; E = E->next()) { print_verbose("GDScript: Reloading: " + E->get()->get_path()); E->get()->load_source_code(E->get()->get_path()); @@ -1686,7 +1692,7 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so #ifdef DEBUG_ENABLED - List<Ref<GDScript> > scripts; + List<Ref<GDScript>> scripts; { MutexLock lock(this->lock); @@ -1702,30 +1708,30 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so //when someone asks you why dynamically typed languages are easier to write.... - Map<Ref<GDScript>, Map<ObjectID, List<Pair<StringName, Variant> > > > to_reload; + Map<Ref<GDScript>, Map<ObjectID, List<Pair<StringName, Variant>>>> to_reload; //as scripts are going to be reloaded, must proceed without locking here scripts.sort_custom<GDScriptDepSort>(); //update in inheritance dependency order - for (List<Ref<GDScript> >::Element *E = scripts.front(); E; E = E->next()) { + for (List<Ref<GDScript>>::Element *E = scripts.front(); E; E = E->next()) { bool reload = E->get() == p_script || to_reload.has(E->get()->get_base()); if (!reload) continue; - to_reload.insert(E->get(), Map<ObjectID, List<Pair<StringName, Variant> > >()); + to_reload.insert(E->get(), Map<ObjectID, List<Pair<StringName, Variant>>>()); if (!p_soft_reload) { //save state and remove script from instances - Map<ObjectID, List<Pair<StringName, Variant> > > &map = to_reload[E->get()]; + Map<ObjectID, List<Pair<StringName, Variant>>> &map = to_reload[E->get()]; while (E->get()->instances.front()) { Object *obj = E->get()->instances.front()->get(); //save instance info - List<Pair<StringName, Variant> > state; + List<Pair<StringName, Variant>> state; if (obj->get_script_instance()) { obj->get_script_instance()->get_property_state(state); @@ -1743,8 +1749,8 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so //save instance info if (obj->get_script_instance()) { - map.insert(obj->get_instance_id(), List<Pair<StringName, Variant> >()); - List<Pair<StringName, Variant> > &state = map[obj->get_instance_id()]; + map.insert(obj->get_instance_id(), List<Pair<StringName, Variant>>()); + List<Pair<StringName, Variant>> &state = map[obj->get_instance_id()]; obj->get_script_instance()->get_property_state(state); obj->set_script(Variant()); } else { @@ -1755,21 +1761,21 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so #endif - for (Map<ObjectID, List<Pair<StringName, Variant> > >::Element *F = E->get()->pending_reload_state.front(); F; F = F->next()) { + for (Map<ObjectID, List<Pair<StringName, Variant>>>::Element *F = E->get()->pending_reload_state.front(); F; F = F->next()) { map[F->key()] = F->get(); //pending to reload, use this one instead } } } - for (Map<Ref<GDScript>, Map<ObjectID, List<Pair<StringName, Variant> > > >::Element *E = to_reload.front(); E; E = E->next()) { + for (Map<Ref<GDScript>, Map<ObjectID, List<Pair<StringName, Variant>>>>::Element *E = to_reload.front(); E; E = E->next()) { Ref<GDScript> scr = E->key(); scr->reload(p_soft_reload); //restore state if saved - for (Map<ObjectID, List<Pair<StringName, Variant> > >::Element *F = E->get().front(); F; F = F->next()) { + for (Map<ObjectID, List<Pair<StringName, Variant>>>::Element *F = E->get().front(); F; F = F->next()) { - List<Pair<StringName, Variant> > &saved_state = F->get(); + List<Pair<StringName, Variant>> &saved_state = F->get(); Object *obj = ObjectDB::get_instance(F->key()); if (!obj) @@ -1793,11 +1799,11 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so if (script_instance->is_placeholder() && scr->is_placeholder_fallback_enabled()) { PlaceHolderScriptInstance *placeholder = static_cast<PlaceHolderScriptInstance *>(script_instance); - for (List<Pair<StringName, Variant> >::Element *G = saved_state.front(); G; G = G->next()) { + for (List<Pair<StringName, Variant>>::Element *G = saved_state.front(); G; G = G->next()) { placeholder->property_set_fallback(G->get().first, G->get().second); } } else { - for (List<Pair<StringName, Variant> >::Element *G = saved_state.front(); G; G = G->next()) { + for (List<Pair<StringName, Variant>>::Element *G = saved_state.front(); G; G = G->next()) { script_instance->set(G->get().first, G->get().second); } } diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 456cd88fe6..3fedc604bf 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -84,8 +84,8 @@ class GDScript : public Script { Map<StringName, Variant> constants; Map<StringName, GDScriptFunction *> member_functions; Map<StringName, MemberInfo> member_indices; //members are just indices to the instanced script. - Map<StringName, Ref<GDScript> > subclasses; - Map<StringName, Vector<StringName> > _signals; + Map<StringName, Ref<GDScript>> subclasses; + Map<StringName, Vector<StringName>> _signals; Vector<ScriptNetData> rpc_functions; Vector<ScriptNetData> rpc_variables; @@ -129,13 +129,14 @@ class GDScript : public Script { #ifdef DEBUG_ENABLED - Map<ObjectID, List<Pair<StringName, Variant> > > pending_reload_state; + Map<ObjectID, List<Pair<StringName, Variant>>> pending_reload_state; #endif bool _update_exports(); void _save_orphaned_subclasses(); + void _init_rpc_methods_properties(); protected: bool _get(const StringName &p_name, Variant &r_ret) const; @@ -150,7 +151,7 @@ protected: public: virtual bool is_valid() const { return valid; } - const Map<StringName, Ref<GDScript> > &get_subclasses() const { return subclasses; } + const Map<StringName, Ref<GDScript>> &get_subclasses() const { return subclasses; } const Map<StringName, Variant> &get_constants() const { return constants; } const Set<StringName> &get_members() const { return members; } const GDScriptDataType &get_member_type(const StringName &p_member) const { @@ -518,7 +519,7 @@ public: virtual void frame(); virtual void get_public_functions(List<MethodInfo> *p_functions) const; - virtual void get_public_constants(List<Pair<String, Variant> > *p_constants) const; + virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const; virtual void profiling_start(); virtual void profiling_stop(); diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 42efdeffbb..fb514aab0c 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -2111,7 +2111,7 @@ Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptPa void GDScriptCompiler::_make_scripts(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) { - Map<StringName, Ref<GDScript> > old_subclasses; + Map<StringName, Ref<GDScript>> old_subclasses; if (p_keep_state) { old_subclasses = p_script->subclasses; diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h index 7d5234a023..34b066b5c7 100644 --- a/modules/gdscript/gdscript_compiler.h +++ b/modules/gdscript/gdscript_compiler.h @@ -48,11 +48,11 @@ class GDScriptCompiler { const GDScriptParser::FunctionNode *function_node; bool debug_stack; - List<Map<StringName, int> > stack_id_stack; + List<Map<StringName, int>> stack_id_stack; Map<StringName, int> stack_identifiers; List<GDScriptFunction::StackDebug> stack_debug; - List<Map<StringName, int> > block_identifier_stack; + List<Map<StringName, int>> block_identifier_stack; Map<StringName, int> block_identifiers; void add_stack_identifier(const StringName &p_id, int p_stackpos) { diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 966a3db840..98e09159ec 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -299,10 +299,10 @@ void GDScriptLanguage::debug_get_stack_level_locals(int p_level, List<String> *p GDScriptFunction *f = _call_stack[l].function; - List<Pair<StringName, int> > locals; + List<Pair<StringName, int>> locals; f->debug_get_stack_member_state(*_call_stack[l].line, &locals); - for (List<Pair<StringName, int> >::Element *E = locals.front(); E; E = E->next()) { + for (List<Pair<StringName, int>>::Element *E = locals.front(); E; E = E->next()) { p_locals->push_back(E->get().first); p_values->push_back(_call_stack[l].stack[E->get().second]); @@ -351,7 +351,7 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant> const Map<StringName, int> &name_idx = GDScriptLanguage::get_singleton()->get_global_map(); const Variant *globals = GDScriptLanguage::get_singleton()->get_global_array(); - List<Pair<String, Variant> > cinfo; + List<Pair<String, Variant>> cinfo; get_public_constants(&cinfo); for (const Map<StringName, int>::Element *E = name_idx.front(); E; E = E->next()) { @@ -360,7 +360,7 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant> continue; bool is_script_constant = false; - for (List<Pair<String, Variant> >::Element *CE = cinfo.front(); CE; CE = CE->next()) { + for (List<Pair<String, Variant>>::Element *CE = cinfo.front(); CE; CE = CE->next()) { if (CE->get().first == E->key()) { is_script_constant = true; break; @@ -434,7 +434,7 @@ void GDScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const } } -void GDScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_constants) const { +void GDScriptLanguage::get_public_constants(List<Pair<String, Variant>> *p_constants) const { Pair<String, Variant> pi; pi.first = "PI"; @@ -1972,7 +1972,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context } } if (!p_only_functions) { - for (const Map<StringName, Ref<GDScript> >::Element *E = script->get_subclasses().front(); E; E = E->next()) { + for (const Map<StringName, Ref<GDScript>>::Element *E = script->get_subclasses().front(); E; E = E->next()) { ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS); r_result.insert(option.display, option); } diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index 3f73654a1e..0721c25388 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -1707,7 +1707,7 @@ struct _GDFKCS { } }; -void GDScriptFunction::debug_get_stack_member_state(int p_line, List<Pair<StringName, int> > *r_stackvars) const { +void GDScriptFunction::debug_get_stack_member_state(int p_line, List<Pair<StringName, int>> *r_stackvars) const { int oc = 0; Map<StringName, _GDFKC> sdmap; diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index 34019e563d..0afffcac73 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -321,7 +321,7 @@ public: GDScript *get_script() const { return _script; } StringName get_source() const { return source; } - void debug_get_stack_member_state(int p_line, List<Pair<StringName, int> > *r_stackvars) const; + void debug_get_stack_member_state(int p_line, List<Pair<StringName, int>> *r_stackvars) const; _FORCE_INLINE_ bool is_empty() const { return _code_size == 0; } diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 353c79d6bb..7fcb2cc423 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -1517,7 +1517,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s } } - //consecutively do unary opeators + //consecutively do unary operators for (int i = expr_pos - 1; i >= next_op; i--) { OperatorNode *op = alloc_node<OperatorNode>(); @@ -8534,7 +8534,7 @@ Error GDScriptParser::_parse(const String &p_base_path) { #ifdef DEBUG_ENABLED // Resolve warning ignores - Vector<Pair<int, String> > warning_skips = tokenizer->get_warning_skips(); + Vector<Pair<int, String>> warning_skips = tokenizer->get_warning_skips(); bool warning_is_error = GLOBAL_GET("debug/gdscript/warnings/treat_warnings_as_errors").booleanize(); for (List<GDScriptWarning>::Element *E = warnings.front(); E;) { GDScriptWarning &w = E->get(); diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h index 3694825d80..1b432ae8c1 100644 --- a/modules/gdscript/gdscript_tokenizer.h +++ b/modules/gdscript/gdscript_tokenizer.h @@ -170,7 +170,7 @@ public: virtual String get_token_error(int p_offset = 0) const = 0; virtual void advance(int p_amount = 1) = 0; #ifdef DEBUG_ENABLED - virtual const Vector<Pair<int, String> > &get_warning_skips() const = 0; + virtual const Vector<Pair<int, String>> &get_warning_skips() const = 0; virtual const Set<String> &get_warning_global_skips() const = 0; virtual bool is_ignoring_warnings() const = 0; #endif // DEBUG_ENABLED @@ -223,7 +223,7 @@ class GDScriptTokenizerText : public GDScriptTokenizer { bool error_flag; #ifdef DEBUG_ENABLED - Vector<Pair<int, String> > warning_skips; + Vector<Pair<int, String>> warning_skips; Set<String> warning_global_skips; bool ignore_warnings; #endif // DEBUG_ENABLED @@ -244,7 +244,7 @@ public: virtual String get_token_error(int p_offset = 0) const; virtual void advance(int p_amount = 1); #ifdef DEBUG_ENABLED - virtual const Vector<Pair<int, String> > &get_warning_skips() const { return warning_skips; } + virtual const Vector<Pair<int, String>> &get_warning_skips() const { return warning_skips; } virtual const Set<String> &get_warning_global_skips() const { return warning_global_skips; } virtual bool is_ignoring_warnings() const { return ignore_warnings; } #endif // DEBUG_ENABLED @@ -283,8 +283,8 @@ public: virtual String get_token_error(int p_offset = 0) const; virtual void advance(int p_amount = 1); #ifdef DEBUG_ENABLED - virtual const Vector<Pair<int, String> > &get_warning_skips() const { - static Vector<Pair<int, String> > v; + virtual const Vector<Pair<int, String>> &get_warning_skips() const { + static Vector<Pair<int, String>> v; return v; } virtual const Set<String> &get_warning_global_skips() const { diff --git a/modules/gdscript/language_server/gdscript_language_protocol.h b/modules/gdscript/language_server/gdscript_language_protocol.h index 3f0ae36af2..d929fd255d 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.h +++ b/modules/gdscript/language_server/gdscript_language_protocol.h @@ -68,7 +68,7 @@ private: static GDScriptLanguageProtocol *singleton; - HashMap<int, Ref<LSPeer> > clients; + HashMap<int, Ref<LSPeer>> clients; Ref<TCP_Server> server; int latest_client_id; int next_client_id; diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 84075f76fd..7273a014f0 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -447,7 +447,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { * and set said multimesh bounding box to one containing all cells which have this item */ - Map<int, List<Pair<Transform, IndexKey> > > multimesh_items; + Map<int, List<Pair<Transform, IndexKey>>> multimesh_items; for (Set<IndexKey>::Element *E = g.cells.front(); E; E = E->next()) { @@ -468,7 +468,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { if (baked_meshes.size() == 0) { if (mesh_library->get_item_mesh(c.item).is_valid()) { if (!multimesh_items.has(c.item)) { - multimesh_items[c.item] = List<Pair<Transform, IndexKey> >(); + multimesh_items[c.item] = List<Pair<Transform, IndexKey>>(); } Pair<Transform, IndexKey> p; @@ -510,7 +510,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { //update multimeshes, only if not baked if (baked_meshes.size() == 0) { - for (Map<int, List<Pair<Transform, IndexKey> > >::Element *E = multimesh_items.front(); E; E = E->next()) { + for (Map<int, List<Pair<Transform, IndexKey>>>::Element *E = multimesh_items.front(); E; E = E->next()) { Octant::MultimeshInstance mmi; RID mm = VS::get_singleton()->multimesh_create(); @@ -518,7 +518,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { VS::get_singleton()->multimesh_set_mesh(mm, mesh_library->get_item_mesh(E->key())->get_rid()); int idx = 0; - for (List<Pair<Transform, IndexKey> >::Element *F = E->get().front(); F; F = F->next()) { + for (List<Pair<Transform, IndexKey>>::Element *F = E->get().front(); F; F = F->next()) { VS::get_singleton()->multimesh_instance_set_transform(mm, idx, F->get().first); #ifdef TOOLS_ENABLED @@ -988,7 +988,7 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe return; //generate - Map<OctantKey, Map<Ref<Material>, Ref<SurfaceTool> > > surface_map; + Map<OctantKey, Map<Ref<Material>, Ref<SurfaceTool>>> surface_map; for (Map<IndexKey, Cell>::Element *E = cell_map.front(); E; E = E->next()) { @@ -1017,10 +1017,10 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe ok.z = key.z / octant_size; if (!surface_map.has(ok)) { - surface_map[ok] = Map<Ref<Material>, Ref<SurfaceTool> >(); + surface_map[ok] = Map<Ref<Material>, Ref<SurfaceTool>>(); } - Map<Ref<Material>, Ref<SurfaceTool> > &mat_map = surface_map[ok]; + Map<Ref<Material>, Ref<SurfaceTool>> &mat_map = surface_map[ok]; for (int i = 0; i < mesh->get_surface_count(); i++) { @@ -1040,11 +1040,11 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe } } - for (Map<OctantKey, Map<Ref<Material>, Ref<SurfaceTool> > >::Element *E = surface_map.front(); E; E = E->next()) { + for (Map<OctantKey, Map<Ref<Material>, Ref<SurfaceTool>>>::Element *E = surface_map.front(); E; E = E->next()) { Ref<ArrayMesh> mesh; mesh.instance(); - for (Map<Ref<Material>, Ref<SurfaceTool> >::Element *F = E->get().front(); F; F = F->next()) { + for (Map<Ref<Material>, Ref<SurfaceTool>>::Element *F = E->get().front(); F; F = F->next()) { F->get()->commit(mesh); } diff --git a/modules/mbedtls/crypto_mbedtls.cpp b/modules/mbedtls/crypto_mbedtls.cpp index ee3c78aeb3..c8a8240a19 100644 --- a/modules/mbedtls/crypto_mbedtls.cpp +++ b/modules/mbedtls/crypto_mbedtls.cpp @@ -234,7 +234,7 @@ Ref<CryptoKey> CryptoMbedTLS::generate_rsa(int p_bytes) { } Ref<X509Certificate> CryptoMbedTLS::generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after) { - Ref<CryptoKeyMbedTLS> key = static_cast<Ref<CryptoKeyMbedTLS> >(p_key); + Ref<CryptoKeyMbedTLS> key = static_cast<Ref<CryptoKeyMbedTLS>>(p_key); ERR_FAIL_COND_V_MSG(key.is_null(), NULL, "Invalid private key argument."); mbedtls_x509write_cert crt; mbedtls_x509write_crt_init(&crt); diff --git a/modules/mbedtls/packet_peer_mbed_dtls.h b/modules/mbedtls/packet_peer_mbed_dtls.h index 26c4543785..b958fa3b95 100755 --- a/modules/mbedtls/packet_peer_mbed_dtls.h +++ b/modules/mbedtls/packet_peer_mbed_dtls.h @@ -67,7 +67,7 @@ protected: public: virtual void poll(); virtual Error accept_peer(Ref<PacketPeerUDP> p_base, Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert = Ref<X509Certificate>(), Ref<X509Certificate> p_ca_chain = Ref<X509Certificate>(), Ref<CookieContextMbedTLS> p_cookies = Ref<CookieContextMbedTLS>()); - virtual Error connect_to_peer(Ref<PacketPeerUDP> p_base, bool p_validate_certs = false, const String &p_for_hostname = String(), Ref<X509Certificate> p_ca_certs = Ref<X509Certificate>()); + virtual Error connect_to_peer(Ref<PacketPeerUDP> p_base, bool p_validate_certs = true, const String &p_for_hostname = String(), Ref<X509Certificate> p_ca_certs = Ref<X509Certificate>()); virtual Status get_status() const; virtual void disconnect_from_peer(); diff --git a/modules/mono/SCsub b/modules/mono/SCsub index 41be367f2f..5f03fafdcf 100644 --- a/modules/mono/SCsub +++ b/modules/mono/SCsub @@ -1,6 +1,5 @@ #!/usr/bin/env python -import build_scripts.tls_configure as tls_configure import build_scripts.mono_configure as mono_configure Import('env') @@ -24,12 +23,6 @@ if env_mono['mono_glue']: if env_mono['tools'] or env_mono['target'] != 'release': env_mono.Append(CPPDEFINES=['GD_MONO_HOT_RELOAD']) -# Configure Thread Local Storage - -conf = Configure(env_mono) -tls_configure.configure(conf) -env_mono = conf.Finish() - # Configure Mono mono_configure.configure(env, env_mono) diff --git a/modules/mono/build_scripts/tls_configure.py b/modules/mono/build_scripts/tls_configure.py deleted file mode 100644 index 622280b00b..0000000000 --- a/modules/mono/build_scripts/tls_configure.py +++ /dev/null @@ -1,36 +0,0 @@ -from __future__ import print_function - -def supported(result): - return 'supported' if result else 'not supported' - - -def check_cxx11_thread_local(conf): - print('Checking for `thread_local` support...', end=" ") - result = conf.TryCompile('thread_local int foo = 0; int main() { return foo; }', '.cpp') - print(supported(result)) - return bool(result) - - -def check_declspec_thread(conf): - print('Checking for `__declspec(thread)` support...', end=" ") - result = conf.TryCompile('__declspec(thread) int foo = 0; int main() { return foo; }', '.cpp') - print(supported(result)) - return bool(result) - - -def check_gcc___thread(conf): - print('Checking for `__thread` support...', end=" ") - result = conf.TryCompile('__thread int foo = 0; int main() { return foo; }', '.cpp') - print(supported(result)) - return bool(result) - - -def configure(conf): - if check_cxx11_thread_local(conf): - conf.env.Append(CPPDEFINES=['HAVE_CXX11_THREAD_LOCAL']) - else: - if conf.env.msvc: - if check_declspec_thread(conf): - conf.env.Append(CPPDEFINES=['HAVE_DECLSPEC_THREAD']) - elif check_gcc___thread(conf): - conf.env.Append(CPPDEFINES=['HAVE_GCC___THREAD']) diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 02ff6bcf13..c1302109a5 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -62,7 +62,6 @@ #include "signal_awaiter_utils.h" #include "utils/macros.h" #include "utils/string_utils.h" -#include "utils/thread_local.h" #define CACHED_STRING_NAME(m_var) (CSharpLanguage::get_singleton()->get_string_names().m_var) @@ -75,7 +74,7 @@ static bool _create_project_solution_if_needed() { if (!FileAccess::exists(sln_path) || !FileAccess::exists(csproj_path)) { // A solution does not yet exist, create a new one - CRASH_COND(CSharpLanguage::get_singleton()->get_godotsharp_editor() == NULL); + CRASH_COND(CSharpLanguage::get_singleton()->get_godotsharp_editor() == nullptr); return CSharpLanguage::get_singleton()->get_godotsharp_editor()->call("CreateProjectSolution"); } @@ -83,7 +82,7 @@ static bool _create_project_solution_if_needed() { } #endif -CSharpLanguage *CSharpLanguage::singleton = NULL; +CSharpLanguage *CSharpLanguage::singleton = nullptr; String CSharpLanguage::get_name() const { @@ -142,14 +141,17 @@ void CSharpLanguage::init() { void CSharpLanguage::finish() { + if (finalized) + return; + finalizing = true; // Make sure all script binding gchandles are released before finalizing GDMono for (Map<Object *, CSharpScriptBinding>::Element *E = script_bindings.front(); E; E = E->next()) { CSharpScriptBinding &script_binding = E->value(); - if (script_binding.gchandle.is_valid()) { - script_binding.gchandle->release(); + if (!script_binding.gchandle.is_released()) { + script_binding.gchandle.release(); script_binding.inited = false; } } @@ -175,7 +177,10 @@ void CSharpLanguage::finish() { } #endif + memdelete(managed_callable_middleman); + finalizing = false; + finalized = true; } void CSharpLanguage::get_reserved_words(List<String> *p_words) const { @@ -434,13 +439,12 @@ static String variant_type_to_managed_name(const String &p_var_type_name) { return "byte[]"; if (p_var_type_name == Variant::get_type_name(Variant::PACKED_INT32_ARRAY)) return "int[]"; - if (p_var_type_name == Variant::get_type_name(Variant::PACKED_FLOAT32_ARRAY)) { -#ifdef REAL_T_IS_DOUBLE - return "double[]"; -#else + if (p_var_type_name == Variant::get_type_name(Variant::PACKED_INT64_ARRAY)) + return "long[]"; + if (p_var_type_name == Variant::get_type_name(Variant::PACKED_FLOAT32_ARRAY)) return "float[]"; -#endif - } + if (p_var_type_name == Variant::get_type_name(Variant::PACKED_FLOAT64_ARRAY)) + return "double[]"; if (p_var_type_name == Variant::get_type_name(Variant::PACKED_STRING_ARRAY)) return "string[]"; if (p_var_type_name == Variant::get_type_name(Variant::PACKED_VECTOR2_ARRAY)) @@ -450,12 +454,18 @@ static String variant_type_to_managed_name(const String &p_var_type_name) { if (p_var_type_name == Variant::get_type_name(Variant::PACKED_COLOR_ARRAY)) return "Color[]"; + if (p_var_type_name == Variant::get_type_name(Variant::SIGNAL)) + return "SignalInfo"; + Variant::Type var_types[] = { Variant::BOOL, Variant::INT, Variant::VECTOR2, + Variant::VECTOR2I, Variant::RECT2, + Variant::RECT2I, Variant::VECTOR3, + Variant::VECTOR3I, Variant::TRANSFORM2D, Variant::PLANE, Variant::QUAT, @@ -463,8 +473,10 @@ static String variant_type_to_managed_name(const String &p_var_type_name) { Variant::BASIS, Variant::TRANSFORM, Variant::COLOR, + Variant::STRING_NAME, Variant::NODE_PATH, - Variant::_RID + Variant::_RID, + Variant::CALLABLE }; for (unsigned int i = 0; i < sizeof(var_types) / sizeof(Variant::Type); i++) { @@ -561,7 +573,13 @@ String CSharpLanguage::debug_get_stack_level_source(int p_level) const { Vector<ScriptLanguage::StackInfo> CSharpLanguage::debug_get_current_stack_info() { #ifdef DEBUG_ENABLED - _TLS_RECURSION_GUARD_V_(Vector<StackInfo>()); + // Printing an error here will result in endless recursion, so we must be careful + static thread_local bool _recursion_flag_ = false; + if (_recursion_flag_) + return Vector<StackInfo>(); + _recursion_flag_ = true; + SCOPE_EXIT { _recursion_flag_ = false; }; + GD_MONO_SCOPE_THREAD_ATTACH; if (!gdmono->is_runtime_initialized() || !GDMono::get_singleton()->get_core_api_assembly() || !GDMonoCache::cached_data.corlib_cache_updated) @@ -586,7 +604,13 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::debug_get_current_stack_info() #ifdef DEBUG_ENABLED Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObject *p_stack_trace) { - _TLS_RECURSION_GUARD_V_(Vector<StackInfo>()); + // Printing an error here will result in endless recursion, so we must be careful + static thread_local bool _recursion_flag_ = false; + if (_recursion_flag_) + return Vector<StackInfo>(); + _recursion_flag_ = true; + SCOPE_EXIT { _recursion_flag_ = false; }; + GD_MONO_SCOPE_THREAD_ATTACH; MonoException *exc = NULL; @@ -655,7 +679,7 @@ void CSharpLanguage::pre_unsafe_unreference(Object *p_obj) { void CSharpLanguage::frame() { if (gdmono && gdmono->is_runtime_initialized() && gdmono->get_core_api_assembly() != NULL) { - const Ref<MonoGCHandle> &task_scheduler_handle = GDMonoCache::cached_data.task_scheduler_handle; + const Ref<MonoGCHandleRef> &task_scheduler_handle = GDMonoCache::cached_data.task_scheduler_handle; if (task_scheduler_handle.is_valid()) { MonoObject *task_scheduler = task_scheduler_handle->get_target(); @@ -763,7 +787,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { // There is no soft reloading with Mono. It's always hard reloading. - List<Ref<CSharpScript> > scripts; + List<Ref<CSharpScript>> scripts; { MutexLock lock(script_instances_mutex); @@ -774,10 +798,40 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { } } - List<Ref<CSharpScript> > to_reload; + scripts.sort_custom<CSharpScriptDepSort>(); // Update in inheritance dependency order + + // Serialize managed callables + { + MutexLock lock(ManagedCallable::instances_mutex); + + for (SelfList<ManagedCallable> *elem = ManagedCallable::instances.first(); elem; elem = elem->next()) { + ManagedCallable *managed_callable = elem->self(); + + MonoDelegate *delegate = (MonoDelegate *)managed_callable->delegate_handle.get_target(); + + Array serialized_data; + MonoObject *managed_serialized_data = GDMonoMarshal::variant_to_mono_object(serialized_data); + + MonoException *exc = NULL; + bool success = (bool)CACHED_METHOD_THUNK(DelegateUtils, TrySerializeDelegate).invoke(delegate, managed_serialized_data, &exc); + + if (exc) { + GDMonoUtils::debug_print_unhandled_exception(exc); + continue; + } + + if (success) { + ManagedCallable::instances_pending_reload.insert(managed_callable, serialized_data); + } else if (OS::get_singleton()->is_stdout_verbose()) { + OS::get_singleton()->print("Failed to serialize delegate\n"); + } + } + } + + List<Ref<CSharpScript>> to_reload; // We need to keep reference instances alive during reloading - List<Ref<Reference> > ref_instances; + List<Ref<Reference>> ref_instances; for (Map<Object *, CSharpScriptBinding>::Element *E = script_bindings.front(); E; E = E->next()) { CSharpScriptBinding &script_binding = E->value(); @@ -789,9 +843,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { // As scripts are going to be reloaded, must proceed without locking here - scripts.sort_custom<CSharpScriptDepSort>(); // Update in inheritance dependency order - - for (List<Ref<CSharpScript> >::Element *E = scripts.front(); E; E = E->next()) { + for (List<Ref<CSharpScript>>::Element *E = scripts.front(); E; E = E->next()) { Ref<CSharpScript> &script = E->get(); to_reload.push_back(script); @@ -845,13 +897,14 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { // TODO: Proper state backup (Not only variants, serialize managed state of scripts) csi->get_properties_state_for_reloading(state.properties); + csi->get_event_signals_state_for_reloading(state.event_signals); owners_map[obj->get_instance_id()] = state; } } // After the state of all instances is saved, clear scripts and script instances - for (List<Ref<CSharpScript> >::Element *E = scripts.front(); E; E = E->next()) { + for (List<Ref<CSharpScript>>::Element *E = scripts.front(); E; E = E->next()) { Ref<CSharpScript> &script = E->get(); while (script->instances.front()) { @@ -866,7 +919,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { if (gdmono->reload_scripts_domain() != OK) { // Failed to reload the scripts domain // Make sure to add the scripts back to their owners before returning - for (List<Ref<CSharpScript> >::Element *E = to_reload.front(); E; E = E->next()) { + for (List<Ref<CSharpScript>>::Element *E = to_reload.front(); E; E = E->next()) { Ref<CSharpScript> scr = E->get(); for (const Map<ObjectID, CSharpScript::StateBackup>::Element *F = scr->pending_reload_state.front(); F; F = F->next()) { @@ -891,7 +944,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { #endif // Restore Variant properties state, it will be kept by the placeholder until the next script reloading - for (List<Pair<StringName, Variant> >::Element *G = scr->pending_reload_state[obj_id].properties.front(); G; G = G->next()) { + for (List<Pair<StringName, Variant>>::Element *G = scr->pending_reload_state[obj_id].properties.front(); G; G = G->next()) { placeholder->property_set_fallback(G->get().first, G->get().second, NULL); } @@ -902,9 +955,9 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { return; } - List<Ref<CSharpScript> > to_reload_state; + List<Ref<CSharpScript>> to_reload_state; - for (List<Ref<CSharpScript> >::Element *E = to_reload.front(); E; E = E->next()) { + for (List<Ref<CSharpScript>>::Element *E = to_reload.front(); E; E = E->next()) { Ref<CSharpScript> script = E->get(); if (!script->get_path().empty()) { @@ -957,7 +1010,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { CSharpScript::initialize_for_managed_type(script, script_class, native); } - String native_name = NATIVE_GDMONOCLASS_NAME(script->native); + StringName native_name = NATIVE_GDMONOCLASS_NAME(script->native); { for (Set<ObjectID>::Element *F = script->pending_reload_instances.front(); F; F = F->next()) { @@ -1012,7 +1065,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { to_reload_state.push_back(script); } - for (List<Ref<CSharpScript> >::Element *E = to_reload_state.front(); E; E = E->next()) { + for (List<Ref<CSharpScript>>::Element *E = to_reload_state.front(); E; E = E->next()) { Ref<CSharpScript> script = E->get(); for (Set<ObjectID>::Element *F = script->pending_reload_instances.front(); F; F = F->next()) { @@ -1030,19 +1083,84 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { CSharpScript::StateBackup &state_backup = script->pending_reload_state[obj_id]; - for (List<Pair<StringName, Variant> >::Element *G = state_backup.properties.front(); G; G = G->next()) { + for (List<Pair<StringName, Variant>>::Element *G = state_backup.properties.front(); G; G = G->next()) { obj->get_script_instance()->set(G->get().first, G->get().second); } - // Call OnAfterDeserialization CSharpInstance *csi = CAST_CSHARP_INSTANCE(obj->get_script_instance()); - if (csi && csi->script->script_class->implements_interface(CACHED_CLASS(ISerializationListener))) - obj->get_script_instance()->call_multilevel(string_names.on_after_deserialize); + + if (csi) { + for (List<Pair<StringName, Array>>::Element *G = state_backup.event_signals.front(); G; G = G->next()) { + const StringName &name = G->get().first; + const Array &serialized_data = G->get().second; + + Map<StringName, CSharpScript::EventSignal>::Element *match = script->event_signals.find(name); + + if (!match) { + // The event or its signal attribute were removed + continue; + } + + const CSharpScript::EventSignal &event_signal = match->value(); + + MonoObject *managed_serialized_data = GDMonoMarshal::variant_to_mono_object(serialized_data); + MonoDelegate *delegate = NULL; + + MonoException *exc = NULL; + bool success = (bool)CACHED_METHOD_THUNK(DelegateUtils, TryDeserializeDelegate).invoke(managed_serialized_data, &delegate, &exc); + + if (exc) { + GDMonoUtils::debug_print_unhandled_exception(exc); + continue; + } + + if (success) { + ERR_CONTINUE(delegate == NULL); + event_signal.field->set_value(csi->get_mono_object(), (MonoObject *)delegate); + } else if (OS::get_singleton()->is_stdout_verbose()) { + OS::get_singleton()->print("Failed to deserialize event signal delegate\n"); + } + } + + // Call OnAfterDeserialization + if (csi->script->script_class->implements_interface(CACHED_CLASS(ISerializationListener))) + obj->get_script_instance()->call_multilevel(string_names.on_after_deserialize); + } } script->pending_reload_instances.clear(); } + // Deserialize managed callables + { + MutexLock lock(ManagedCallable::instances_mutex); + + for (Map<ManagedCallable *, Array>::Element *elem = ManagedCallable::instances_pending_reload.front(); elem; elem = elem->next()) { + ManagedCallable *managed_callable = elem->key(); + const Array &serialized_data = elem->value(); + + MonoObject *managed_serialized_data = GDMonoMarshal::variant_to_mono_object(serialized_data); + MonoDelegate *delegate = NULL; + + MonoException *exc = NULL; + bool success = (bool)CACHED_METHOD_THUNK(DelegateUtils, TryDeserializeDelegate).invoke(managed_serialized_data, &delegate, &exc); + + if (exc) { + GDMonoUtils::debug_print_unhandled_exception(exc); + continue; + } + + if (success) { + ERR_CONTINUE(delegate == NULL); + managed_callable->set_delegate(delegate); + } else if (OS::get_singleton()->is_stdout_verbose()) { + OS::get_singleton()->print("Failed to deserialize delegate\n"); + } + } + + ManagedCallable::instances_pending_reload.clear(); + } + #ifdef TOOLS_ENABLED // FIXME: Hack to refresh editor in order to display new properties and signals. See if there is a better alternative. if (Engine::get_singleton()->is_editor_hint()) { @@ -1163,9 +1281,20 @@ bool CSharpLanguage::debug_break(const String &p_error, bool p_allow_continue) { void CSharpLanguage::_on_scripts_domain_unloaded() { for (Map<Object *, CSharpScriptBinding>::Element *E = script_bindings.front(); E; E = E->next()) { CSharpScriptBinding &script_binding = E->value(); + script_binding.gchandle.release(); script_binding.inited = false; } + { + MutexLock lock(ManagedCallable::instances_mutex); + + for (SelfList<ManagedCallable> *elem = ManagedCallable::instances.first(); elem; elem = elem->next()) { + ManagedCallable *managed_callable = elem->self(); + managed_callable->delegate_handle.release(); + managed_callable->delegate_invoke = NULL; + } + } + scripts_metadata_invalidated = true; } @@ -1203,57 +1332,45 @@ void CSharpLanguage::set_language_index(int p_idx) { lang_idx = p_idx; } -void CSharpLanguage::release_script_gchandle(Ref<MonoGCHandle> &p_gchandle) { +void CSharpLanguage::release_script_gchandle(MonoGCHandleData &p_gchandle) { - if (!p_gchandle->is_released()) { // Do not lock unnecessarily + if (!p_gchandle.is_released()) { // Do not lock unnecessarily MutexLock lock(get_singleton()->script_gchandle_release_mutex); - p_gchandle->release(); + p_gchandle.release(); } } -void CSharpLanguage::release_script_gchandle(MonoObject *p_expected_obj, Ref<MonoGCHandle> &p_gchandle) { +void CSharpLanguage::release_script_gchandle(MonoObject *p_expected_obj, MonoGCHandleData &p_gchandle) { - uint32_t pinned_gchandle = MonoGCHandle::new_strong_handle_pinned(p_expected_obj); // We might lock after this, so pin it + uint32_t pinned_gchandle = GDMonoUtils::new_strong_gchandle_pinned(p_expected_obj); // We might lock after this, so pin it - if (!p_gchandle->is_released()) { // Do not lock unnecessarily + if (!p_gchandle.is_released()) { // Do not lock unnecessarily MutexLock lock(get_singleton()->script_gchandle_release_mutex); - MonoObject *target = p_gchandle->get_target(); + MonoObject *target = p_gchandle.get_target(); // We release the gchandle if it points to the MonoObject* we expect (otherwise it was // already released and could have been replaced) or if we can't get its target MonoObject* // (which doesn't necessarily mean it was released, and we want it released in order to // avoid locking other threads unnecessarily). if (target == p_expected_obj || target == NULL) { - p_gchandle->release(); + p_gchandle.release(); } } - MonoGCHandle::free_handle(pinned_gchandle); + GDMonoUtils::free_gchandle(pinned_gchandle); } CSharpLanguage::CSharpLanguage() { ERR_FAIL_COND_MSG(singleton, "C# singleton already exist."); singleton = this; - - finalizing = false; - - gdmono = NULL; - - lang_idx = -1; - - scripts_metadata_invalidated = true; - -#ifdef TOOLS_ENABLED - godotsharp_editor = NULL; -#endif } CSharpLanguage::~CSharpLanguage() { finish(); - singleton = NULL; + singleton = nullptr; } bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_binding, Object *p_object) { @@ -1286,7 +1403,7 @@ bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_b r_script_binding.inited = true; r_script_binding.type_name = type_name; r_script_binding.wrapper_class = type_class; // cache - r_script_binding.gchandle = MonoGCHandle::create_strong(mono_object); + r_script_binding.gchandle = MonoGCHandleData::new_strong_handle(mono_object); r_script_binding.owner = p_object; // Tie managed to unmanaged @@ -1351,10 +1468,11 @@ void CSharpLanguage::free_instance_binding_data(void *p_data) { if (script_binding.inited) { // Set the native instance field to IntPtr.Zero, if not yet garbage collected. // This is done to avoid trying to dispose the native instance from Dispose(bool). - MonoObject *mono_object = script_binding.gchandle->get_target(); + MonoObject *mono_object = script_binding.gchandle.get_target(); if (mono_object) { CACHED_FIELD(GodotObject, ptr)->set_value_raw(mono_object, NULL); } + script_binding.gchandle.release(); } script_bindings.erase(data); @@ -1374,26 +1492,26 @@ void CSharpLanguage::refcount_incremented_instance_binding(Object *p_object) { CRASH_COND(!data); CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get(); - Ref<MonoGCHandle> &gchandle = script_binding.gchandle; + MonoGCHandleData &gchandle = script_binding.gchandle; if (!script_binding.inited) return; - if (ref_owner->reference_get_count() > 1 && gchandle->is_weak()) { // The managed side also holds a reference, hence 1 instead of 0 + if (ref_owner->reference_get_count() > 1 && gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0 GD_MONO_SCOPE_THREAD_ATTACH; // The reference count was increased after the managed side was the only one referencing our owner. // This means the owner is being referenced again by the unmanaged side, // so the owner must hold the managed side alive again to avoid it from being GCed. - MonoObject *target = gchandle->get_target(); + MonoObject *target = gchandle.get_target(); if (!target) return; // Called after the managed side was collected, so nothing to do here // Release the current weak handle and replace it with a strong handle. - uint32_t strong_gchandle = MonoGCHandle::new_strong_handle(target); - gchandle->release(); - gchandle->set_handle(strong_gchandle, MonoGCHandle::STRONG_HANDLE); + MonoGCHandleData strong_gchandle = MonoGCHandleData::new_strong_handle(target); + gchandle.release(); + gchandle = strong_gchandle; } } @@ -1410,27 +1528,27 @@ bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) { CRASH_COND(!data); CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get(); - Ref<MonoGCHandle> &gchandle = script_binding.gchandle; + MonoGCHandleData &gchandle = script_binding.gchandle; int refcount = ref_owner->reference_get_count(); if (!script_binding.inited) return refcount == 0; - if (refcount == 1 && gchandle.is_valid() && !gchandle->is_weak()) { // The managed side also holds a reference, hence 1 instead of 0 + if (refcount == 1 && !gchandle.is_released() && !gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0 GD_MONO_SCOPE_THREAD_ATTACH; // If owner owner is no longer referenced by the unmanaged side, // the managed instance takes responsibility of deleting the owner when GCed. - MonoObject *target = gchandle->get_target(); + MonoObject *target = gchandle.get_target(); if (!target) return refcount == 0; // Called after the managed side was collected, so nothing to do here // Release the current strong handle and replace it with a weak handle. - uint32_t weak_gchandle = MonoGCHandle::new_weak_handle(target); - gchandle->release(); - gchandle->set_handle(weak_gchandle, MonoGCHandle::WEAK_HANDLE); + MonoGCHandleData weak_gchandle = MonoGCHandleData::new_weak_handle(target); + gchandle.release(); + gchandle = weak_gchandle; return false; } @@ -1438,14 +1556,13 @@ bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) { return refcount == 0; } -CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpScript *p_script, const Ref<MonoGCHandle> &p_gchandle) { +CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpScript *p_script, const MonoGCHandleData &p_gchandle) { - CSharpInstance *instance = memnew(CSharpInstance); + CSharpInstance *instance = memnew(CSharpInstance(Ref<CSharpScript>(p_script))); Reference *ref = Object::cast_to<Reference>(p_owner); instance->base_ref = ref != NULL; - instance->script = Ref<CSharpScript>(p_script); instance->owner = p_owner; instance->gchandle = p_gchandle; @@ -1459,8 +1576,8 @@ CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpS MonoObject *CSharpInstance::get_mono_object() const { - ERR_FAIL_COND_V(gchandle.is_null(), NULL); - return gchandle->get_target(); + ERR_FAIL_COND_V(gchandle.is_released(), NULL); + return gchandle.get_target(); } Object *CSharpInstance::get_owner() { @@ -1585,7 +1702,7 @@ bool CSharpInstance::get(const StringName &p_name, Variant &r_ret) const { return false; } -void CSharpInstance::get_properties_state_for_reloading(List<Pair<StringName, Variant> > &r_state) { +void CSharpInstance::get_properties_state_for_reloading(List<Pair<StringName, Variant>> &r_state) { List<PropertyInfo> pinfo; get_property_list(&pinfo); @@ -1610,6 +1727,37 @@ void CSharpInstance::get_properties_state_for_reloading(List<Pair<StringName, Va } } +void CSharpInstance::get_event_signals_state_for_reloading(List<Pair<StringName, Array>> &r_state) { + + MonoObject *owner_managed = get_mono_object(); + ERR_FAIL_NULL(owner_managed); + + for (const Map<StringName, CSharpScript::EventSignal>::Element *E = script->event_signals.front(); E; E = E->next()) { + const CSharpScript::EventSignal &event_signal = E->value(); + + MonoDelegate *delegate_field_value = (MonoDelegate *)event_signal.field->get_value(owner_managed); + if (!delegate_field_value) + continue; // Empty + + Array serialized_data; + MonoObject *managed_serialized_data = GDMonoMarshal::variant_to_mono_object(serialized_data); + + MonoException *exc = NULL; + bool success = (bool)CACHED_METHOD_THUNK(DelegateUtils, TrySerializeDelegate).invoke(delegate_field_value, managed_serialized_data, &exc); + + if (exc) { + GDMonoUtils::debug_print_unhandled_exception(exc); + continue; + } + + if (success) { + r_state.push_back(Pair<StringName, Array>(event_signal.field->get_name(), serialized_data)); + } else if (OS::get_singleton()->is_stdout_verbose()) { + OS::get_singleton()->print("Failed to serialize event signal delegate\n"); + } + } +} + void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const { for (Map<StringName, PropertyInfo>::Element *E = script->member_info.front(); E; E = E->next()) { @@ -1802,10 +1950,6 @@ bool CSharpInstance::_unreference_owner_unsafe() { } MonoObject *CSharpInstance::_internal_new_managed() { -#ifdef DEBUG_ENABLED - CRASH_COND(!gchandle.is_valid()); -#endif - // Search the constructor first, to fail with an error if it's not found before allocating anything else. GDMonoMethod *ctor = script->script_class->get_method(CACHED_STRING_NAME(dotctor), 0); ERR_FAIL_NULL_V_MSG(ctor, NULL, @@ -1832,7 +1976,7 @@ MonoObject *CSharpInstance::_internal_new_managed() { } // Tie managed to unmanaged - gchandle = MonoGCHandle::create_strong(mono_object); + gchandle = MonoGCHandleData::new_strong_handle(mono_object); if (base_ref) _reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback) @@ -1847,9 +1991,11 @@ MonoObject *CSharpInstance::_internal_new_managed() { void CSharpInstance::mono_object_disposed(MonoObject *p_obj) { + disconnect_event_signals(); + #ifdef DEBUG_ENABLED CRASH_COND(base_ref); - CRASH_COND(gchandle.is_null()); + CRASH_COND(gchandle.is_released()); #endif CSharpLanguage::get_singleton()->release_script_gchandle(p_obj, gchandle); } @@ -1858,7 +2004,7 @@ void CSharpInstance::mono_object_disposed_baseref(MonoObject *p_obj, bool p_is_f #ifdef DEBUG_ENABLED CRASH_COND(!base_ref); - CRASH_COND(gchandle.is_null()); + CRASH_COND(gchandle.is_released()); #endif r_remove_script_instance = false; @@ -1888,6 +2034,33 @@ void CSharpInstance::mono_object_disposed_baseref(MonoObject *p_obj, bool p_is_f } } +void CSharpInstance::connect_event_signals() { + for (const Map<StringName, CSharpScript::EventSignal>::Element *E = script->event_signals.front(); E; E = E->next()) { + const CSharpScript::EventSignal &event_signal = E->value(); + + StringName signal_name = event_signal.field->get_name(); + + // TODO: Use pooling for ManagedCallable instances. + auto event_signal_callable = memnew(EventSignalCallable(owner, &event_signal)); + + owner->connect(signal_name, Callable(event_signal_callable)); + } +} + +void CSharpInstance::disconnect_event_signals() { + for (const Map<StringName, CSharpScript::EventSignal>::Element *E = script->event_signals.front(); E; E = E->next()) { + const CSharpScript::EventSignal &event_signal = E->value(); + + StringName signal_name = event_signal.field->get_name(); + + // TODO: It would be great if we could store this EventSignalCallable on the stack. + // The problem is that Callable memdeletes it when it's destructed... + auto event_signal_callable = memnew(EventSignalCallable(owner, &event_signal)); + + owner->disconnect(signal_name, Callable(event_signal_callable)); + } +} + void CSharpInstance::refcount_incremented() { #ifdef DEBUG_ENABLED @@ -1897,7 +2070,7 @@ void CSharpInstance::refcount_incremented() { Reference *ref_owner = Object::cast_to<Reference>(owner); - if (ref_owner->reference_get_count() > 1 && gchandle->is_weak()) { // The managed side also holds a reference, hence 1 instead of 0 + if (ref_owner->reference_get_count() > 1 && gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0 GD_MONO_SCOPE_THREAD_ATTACH; // The reference count was increased after the managed side was the only one referencing our owner. @@ -1905,9 +2078,9 @@ void CSharpInstance::refcount_incremented() { // so the owner must hold the managed side alive again to avoid it from being GCed. // Release the current weak handle and replace it with a strong handle. - uint32_t strong_gchandle = MonoGCHandle::new_strong_handle(gchandle->get_target()); - gchandle->release(); - gchandle->set_handle(strong_gchandle, MonoGCHandle::STRONG_HANDLE); + MonoGCHandleData strong_gchandle = MonoGCHandleData::new_strong_handle(gchandle.get_target()); + gchandle.release(); + gchandle = strong_gchandle; } } @@ -1922,16 +2095,16 @@ bool CSharpInstance::refcount_decremented() { int refcount = ref_owner->reference_get_count(); - if (refcount == 1 && !gchandle->is_weak()) { // The managed side also holds a reference, hence 1 instead of 0 + if (refcount == 1 && !gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0 GD_MONO_SCOPE_THREAD_ATTACH; // If owner owner is no longer referenced by the unmanaged side, // the managed instance takes responsibility of deleting the owner when GCed. // Release the current strong handle and replace it with a weak handle. - uint32_t weak_gchandle = MonoGCHandle::new_weak_handle(gchandle->get_target()); - gchandle->release(); - gchandle->set_handle(weak_gchandle, MonoGCHandle::WEAK_HANDLE); + MonoGCHandleData weak_gchandle = MonoGCHandleData::new_weak_handle(gchandle.get_target()); + gchandle.release(); + gchandle = weak_gchandle; return false; } @@ -2087,13 +2260,8 @@ ScriptLanguage *CSharpInstance::get_language() { return CSharpLanguage::get_singleton(); } -CSharpInstance::CSharpInstance() : - owner(NULL), - base_ref(false), - ref_dying(false), - unsafe_referenced(false), - predelete_notified(false), - destructing_script_instance(false) { +CSharpInstance::CSharpInstance(const Ref<CSharpScript> &p_script) : + script(p_script) { } CSharpInstance::~CSharpInstance() { @@ -2102,7 +2270,7 @@ CSharpInstance::~CSharpInstance() { destructing_script_instance = true; - if (gchandle.is_valid()) { + if (!gchandle.is_released()) { if (!predelete_notified && !ref_dying) { // This destructor is not called from the owners destructor. // This could be being called from the owner's set_script_instance method, @@ -2110,7 +2278,7 @@ CSharpInstance::~CSharpInstance() { // we must call Dispose here, because Dispose calls owner->set_script_instance(NULL) // and that would mess up with the new script instance if called later. - MonoObject *mono_object = gchandle->get_target(); + MonoObject *mono_object = gchandle.get_target(); if (mono_object) { MonoException *exc = NULL; @@ -2122,7 +2290,7 @@ CSharpInstance::~CSharpInstance() { } } - gchandle->release(); // Make sure the gchandle is released + gchandle.release(); // Make sure the gchandle is released } // If not being called from the owner's destructor, and we still hold a reference to the owner @@ -2282,7 +2450,7 @@ bool CSharpScript::_update_exports() { return false; } - uint32_t tmp_pinned_gchandle = MonoGCHandle::new_strong_handle_pinned(tmp_object); // pin it (not sure if needed) + uint32_t tmp_pinned_gchandle = GDMonoUtils::new_strong_gchandle_pinned(tmp_object); // pin it (not sure if needed) GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), 0); @@ -2297,7 +2465,7 @@ bool CSharpScript::_update_exports() { if (ctor_exc) { // TODO: Should we free 'tmp_native' if the exception was thrown after its creation? - MonoGCHandle::free_handle(tmp_pinned_gchandle); + GDMonoUtils::free_gchandle(tmp_pinned_gchandle); tmp_object = NULL; ERR_PRINT("Exception thrown from constructor of temporary MonoObject:"); @@ -2376,7 +2544,7 @@ bool CSharpScript::_update_exports() { GDMonoUtils::debug_print_unhandled_exception(exc); } - MonoGCHandle::free_handle(tmp_pinned_gchandle); + GDMonoUtils::free_gchandle(tmp_pinned_gchandle); tmp_object = NULL; if (tmp_native && !base_ref) { @@ -2416,6 +2584,7 @@ void CSharpScript::load_script_signals(GDMonoClass *p_class, GDMonoClass *p_nati // make sure this classes signals are empty when loading for the first time _signals.clear(); + event_signals.clear(); GD_MONO_SCOPE_THREAD_ATTACH; @@ -2423,56 +2592,90 @@ void CSharpScript::load_script_signals(GDMonoClass *p_class, GDMonoClass *p_nati while (top && top != p_native_class) { const Vector<GDMonoClass *> &delegates = top->get_all_delegates(); for (int i = delegates.size() - 1; i >= 0; --i) { - Vector<Argument> parameters; - GDMonoClass *delegate = delegates[i]; - if (_get_signal(top, delegate, parameters)) { + if (!delegate->has_attribute(CACHED_CLASS(SignalAttribute))) + continue; + + // Arguments are accessibles as arguments of .Invoke method + GDMonoMethod *invoke_method = delegate->get_method(mono_get_delegate_invoke(delegate->get_mono_ptr())); + + Vector<SignalParameter> parameters; + if (_get_signal(top, invoke_method, parameters)) { _signals[delegate->get_name()] = parameters; } } + List<StringName> found_event_signals; + + void *iter = NULL; + MonoEvent *raw_event = NULL; + while ((raw_event = mono_class_get_events(top->get_mono_ptr(), &iter)) != NULL) { + MonoCustomAttrInfo *event_attrs = mono_custom_attrs_from_event(top->get_mono_ptr(), raw_event); + if (event_attrs) { + if (mono_custom_attrs_has_attr(event_attrs, CACHED_CLASS(SignalAttribute)->get_mono_ptr())) { + const char *event_name = mono_event_get_name(raw_event); + found_event_signals.push_back(StringName(event_name)); + } + + mono_custom_attrs_free(event_attrs); + } + } + + const Vector<GDMonoField *> &fields = top->get_all_fields(); + for (int i = 0; i < fields.size(); i++) { + GDMonoField *field = fields[i]; + + GDMonoClass *field_class = field->get_type().type_class; + + if (!mono_class_is_delegate(field_class->get_mono_ptr())) + continue; + + if (!found_event_signals.find(field->get_name())) + continue; + + GDMonoMethod *invoke_method = field_class->get_method(mono_get_delegate_invoke(field_class->get_mono_ptr())); + + Vector<SignalParameter> parameters; + if (_get_signal(top, invoke_method, parameters)) { + event_signals[field->get_name()] = { field, invoke_method, parameters }; + } + } + top = top->get_parent_class(); } signals_invalidated = false; } -bool CSharpScript::_get_signal(GDMonoClass *p_class, GDMonoClass *p_delegate, Vector<Argument> ¶ms) { +bool CSharpScript::_get_signal(GDMonoClass *p_class, GDMonoMethod *p_delegate_invoke, Vector<SignalParameter> ¶ms) { GD_MONO_ASSERT_THREAD_ATTACHED; - if (p_delegate->has_attribute(CACHED_CLASS(SignalAttribute))) { - MonoType *raw_type = p_delegate->get_mono_type(); + Vector<StringName> names; + Vector<ManagedType> types; + p_delegate_invoke->get_parameter_names(names); + p_delegate_invoke->get_parameter_types(types); - if (mono_type_get_type(raw_type) == MONO_TYPE_CLASS) { - // Arguments are accessibles as arguments of .Invoke method - GDMonoMethod *invoke = p_delegate->get_method("Invoke", -1); - - Vector<StringName> names; - Vector<ManagedType> types; - invoke->get_parameter_names(names); - invoke->get_parameter_types(types); - - if (names.size() == types.size()) { - for (int i = 0; i < names.size(); ++i) { - Argument arg; - arg.name = names[i]; - arg.type = GDMonoMarshal::managed_to_variant_type(types[i]); - - if (arg.type == Variant::NIL) { - ERR_PRINT("Unknown type of signal parameter: '" + arg.name + "' in '" + p_class->get_full_name() + "'."); - return false; - } + for (int i = 0; i < names.size(); ++i) { + SignalParameter arg; + arg.name = names[i]; - params.push_back(arg); - } + bool nil_is_variant = false; + arg.type = GDMonoMarshal::managed_to_variant_type(types[i], &nil_is_variant); - return true; + if (arg.type == Variant::NIL) { + if (nil_is_variant) { + arg.nil_is_variant = true; + } else { + ERR_PRINT("Unknown type of signal parameter: '" + arg.name + "' in '" + p_class->get_full_name() + "'."); + return false; } } + + params.push_back(arg); } - return false; + return true; } #ifdef TOOLS_ENABLED @@ -2523,7 +2726,8 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect } } - Variant::Type variant_type = GDMonoMarshal::managed_to_variant_type(type); + bool nil_is_variant = false; + Variant::Type variant_type = GDMonoMarshal::managed_to_variant_type(type, &nil_is_variant); if (!p_inspect_export || !exported) { r_prop_info = PropertyInfo(variant_type, (String)p_member->get_name(), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_SCRIPT_VARIABLE); @@ -2536,7 +2740,7 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect PropertyHint hint = PROPERTY_HINT_NONE; String hint_string; - if (variant_type == Variant::NIL) { + if (variant_type == Variant::NIL && !nil_is_variant) { ERR_PRINT("Unknown exported member type: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'."); return false; } @@ -2552,7 +2756,14 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect hint_string = CACHED_FIELD(ExportAttribute, hintString)->get_string_value(attr); } - r_prop_info = PropertyInfo(variant_type, (String)p_member->get_name(), hint, hint_string, PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE); + uint32_t prop_usage = PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE; + + if (variant_type == Variant::NIL) { + // System.Object (Variant) + prop_usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + } + + r_prop_info = PropertyInfo(variant_type, (String)p_member->get_name(), hint, hint_string, prop_usage); r_exported = true; return true; @@ -2562,6 +2773,11 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, ManagedType p_type, Variant::Type p_variant_type, bool p_allow_generics, PropertyHint &r_hint, String &r_hint_string) { + if (p_variant_type == Variant::NIL) { + // System.Object (Variant) + return 1; + } + GD_MONO_ASSERT_THREAD_ATTACHED; if (p_variant_type == Variant::INT && p_type.type_encoding == MONO_TYPE_VALUETYPE && mono_class_is_enum(p_type.type_class->get_mono_ptr())) { @@ -2621,7 +2837,7 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage CRASH_COND(field_native_class == NULL); r_hint = PROPERTY_HINT_RESOURCE_TYPE; - r_hint_string = NATIVE_GDMONOCLASS_NAME(field_native_class); + r_hint_string = String(NATIVE_GDMONOCLASS_NAME(field_native_class)); } else if (p_allow_generics && p_variant_type == Variant::ARRAY) { // Nested arrays are not supported in the inspector @@ -2894,8 +3110,8 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg CRASH_COND(data == NULL); CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get(); - if (script_binding.inited && script_binding.gchandle.is_valid()) { - MonoObject *mono_object = script_binding.gchandle->get_target(); + if (script_binding.inited && !script_binding.gchandle.is_released()) { + MonoObject *mono_object = script_binding.gchandle.get_target(); if (mono_object) { MonoException *exc = NULL; GDMonoUtils::dispose(mono_object, &exc); @@ -2905,13 +3121,13 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg } } + script_binding.gchandle.release(); // Just in case script_binding.inited = false; } } - CSharpInstance *instance = memnew(CSharpInstance); + CSharpInstance *instance = memnew(CSharpInstance(Ref<CSharpScript>(this))); instance->base_ref = p_isref; - instance->script = Ref<CSharpScript>(this); instance->owner = p_owner; instance->owner->set_script_instance(instance); @@ -2934,7 +3150,7 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg } // Tie managed to unmanaged - instance->gchandle = MonoGCHandle::create_strong(mono_object); + instance->gchandle = MonoGCHandleData::new_strong_handle(mono_object); if (instance->base_ref) instance->_reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback) @@ -2998,12 +3214,14 @@ ScriptInstance *CSharpScript::instance_create(Object *p_this) { #endif if (native) { - String native_name = NATIVE_GDMONOCLASS_NAME(native); + StringName native_name = NATIVE_GDMONOCLASS_NAME(native); if (!ClassDB::is_parent_class(p_this->get_class_name(), native_name)) { if (EngineDebugger::is_active()) { - CSharpLanguage::get_singleton()->debug_break_parse(get_path(), 0, "Script inherits from native type '" + native_name + "', so it can't be instanced in object of type: '" + p_this->get_class() + "'"); + CSharpLanguage::get_singleton()->debug_break_parse(get_path(), 0, + "Script inherits from native type '" + String(native_name) + + "', so it can't be instanced in object of type: '" + p_this->get_class() + "'"); } - ERR_FAIL_V_MSG(NULL, "Script inherits from native type '" + native_name + + ERR_FAIL_V_MSG(NULL, "Script inherits from native type '" + String(native_name) + "', so it can't be instanced in object of type: '" + p_this->get_class() + "'."); } } @@ -3290,19 +3508,45 @@ void CSharpScript::update_exports() { } bool CSharpScript::has_script_signal(const StringName &p_signal) const { - return _signals.has(p_signal); + return event_signals.has(p_signal) || _signals.has(p_signal); } void CSharpScript::get_script_signal_list(List<MethodInfo> *r_signals) const { - for (const Map<StringName, Vector<Argument> >::Element *E = _signals.front(); E; E = E->next()) { + + for (const Map<StringName, Vector<SignalParameter>>::Element *E = _signals.front(); E; E = E->next()) { MethodInfo mi; + mi.name = E->key(); + + const Vector<SignalParameter> ¶ms = E->value(); + for (int i = 0; i < params.size(); i++) { + const SignalParameter ¶m = params[i]; + + PropertyInfo arg_info = PropertyInfo(param.type, param.name); + if (param.type == Variant::NIL && param.nil_is_variant) + arg_info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + + mi.arguments.push_back(arg_info); + } + + r_signals->push_back(mi); + } + for (const Map<StringName, EventSignal>::Element *E = event_signals.front(); E; E = E->next()) { + MethodInfo mi; mi.name = E->key(); - for (int i = 0; i < E->get().size(); i++) { - PropertyInfo arg; - arg.name = E->get()[i].name; - mi.arguments.push_back(arg); + + const EventSignal &event_signal = E->value(); + const Vector<SignalParameter> ¶ms = event_signal.parameters; + for (int i = 0; i < params.size(); i++) { + const SignalParameter ¶m = params[i]; + + PropertyInfo arg_info = PropertyInfo(param.type, param.name); + if (param.type == Variant::NIL && param.nil_is_variant) + arg_info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + + mi.arguments.push_back(arg_info); } + r_signals->push_back(mi); } } @@ -3420,19 +3664,10 @@ StringName CSharpScript::get_script_name() const { return name; } -CSharpScript::CSharpScript() : - script_list(this) { +CSharpScript::CSharpScript() { _clear(); -#ifdef TOOLS_ENABLED - source_changed_cache = false; - placeholder_fallback_enabled = false; - exports_invalidated = true; -#endif - - signals_invalidated = true; - _resource_path_changed(); #ifdef DEBUG_ENABLED @@ -3561,4 +3796,5 @@ CSharpLanguage::StringNameCache::StringNameCache() { on_before_serialize = StaticCString::create("OnBeforeSerialize"); on_after_deserialize = StaticCString::create("OnAfterDeserialize"); dotctor = StaticCString::create(".ctor"); + delegate_invoke_method_name = StaticCString::create("Invoke"); } diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 18c53aab52..53b4aa6c20 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -53,8 +53,8 @@ class CSharpLanguage; template <typename TScriptInstance, typename TScriptLanguage> TScriptInstance *cast_script_instance(ScriptInstance *p_inst) { if (!p_inst) - return NULL; - return p_inst->get_language() == TScriptLanguage::get_singleton() ? static_cast<TScriptInstance *>(p_inst) : NULL; + return nullptr; + return p_inst->get_language() == TScriptLanguage::get_singleton() ? static_cast<TScriptInstance *>(p_inst) : nullptr; } #else template <typename TScriptInstance, typename TScriptLanguage> @@ -69,18 +69,32 @@ class CSharpScript : public Script { GDCLASS(CSharpScript, Script); +public: + struct SignalParameter { + String name; + Variant::Type type; + bool nil_is_variant = false; + }; + + struct EventSignal { + GDMonoField *field = NULL; + GDMonoMethod *invoke_method = NULL; + Vector<SignalParameter> parameters; + }; + +private: friend class CSharpInstance; friend class CSharpLanguage; friend struct CSharpScriptDepSort; - bool tool; - bool valid; + bool tool = false; + bool valid = false; bool builtin; - GDMonoClass *base; - GDMonoClass *native; - GDMonoClass *script_class; + GDMonoClass *base = nullptr; + GDMonoClass *native = nullptr; + GDMonoClass *script_class = nullptr; Ref<CSharpScript> base_cache; // TODO what's this for? @@ -91,7 +105,8 @@ class CSharpScript : public Script { // TODO // Replace with buffer containing the serialized state of managed scripts. // Keep variant state backup to use only with script instance placeholders. - List<Pair<StringName, Variant> > properties; + List<Pair<StringName, Variant>> properties; + List<Pair<StringName, Array>> event_signals; }; Set<ObjectID> pending_reload_instances; @@ -103,15 +118,11 @@ class CSharpScript : public Script { String source; StringName name; - SelfList<CSharpScript> script_list; - - struct Argument { - String name; - Variant::Type type; - }; + SelfList<CSharpScript> script_list = this; - Map<StringName, Vector<Argument> > _signals; - bool signals_invalidated; + Map<StringName, Vector<SignalParameter>> _signals; + Map<StringName, EventSignal> event_signals; + bool signals_invalidated = true; Vector<ScriptNetData> rpc_functions; Vector<ScriptNetData> rpc_variables; @@ -120,9 +131,9 @@ class CSharpScript : public Script { List<PropertyInfo> exported_members_cache; // members_cache Map<StringName, Variant> exported_members_defval_cache; // member_default_values_cache Set<PlaceHolderScriptInstance *> placeholders; - bool source_changed_cache; - bool placeholder_fallback_enabled; - bool exports_invalidated; + bool source_changed_cache = false; + bool placeholder_fallback_enabled = false; + bool exports_invalidated = true; void _update_exports_values(Map<StringName, Variant> &values, List<PropertyInfo> &propnames); void _update_member_info_no_exports(); virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder); @@ -133,7 +144,7 @@ class CSharpScript : public Script { void _clear(); void load_script_signals(GDMonoClass *p_class, GDMonoClass *p_native_class); - bool _get_signal(GDMonoClass *p_class, GDMonoClass *p_delegate, Vector<Argument> ¶ms); + bool _get_signal(GDMonoClass *p_class, GDMonoMethod *p_delegate_invoke, Vector<SignalParameter> ¶ms); bool _update_exports(); #ifdef TOOLS_ENABLED @@ -221,15 +232,17 @@ class CSharpInstance : public ScriptInstance { friend class CSharpScript; friend class CSharpLanguage; - Object *owner; - bool base_ref; - bool ref_dying; - bool unsafe_referenced; - bool predelete_notified; - bool destructing_script_instance; + Object *owner = nullptr; + bool base_ref = false; + bool ref_dying = false; + bool unsafe_referenced = false; + bool predelete_notified = false; + bool destructing_script_instance = false; Ref<CSharpScript> script; - Ref<MonoGCHandle> gchandle; + MonoGCHandleData gchandle; + + Vector<Callable> event_signal_callables; bool _reference_owner_unsafe(); @@ -239,17 +252,18 @@ class CSharpInstance : public ScriptInstance { bool _unreference_owner_unsafe(); /* - * If NULL is returned, the caller must destroy the script instance by removing it from its owner. + * If nullptr is returned, the caller must destroy the script instance by removing it from its owner. */ MonoObject *_internal_new_managed(); // Do not use unless you know what you are doing friend void GDMonoInternals::tie_managed_to_unmanaged(MonoObject *, Object *); - static CSharpInstance *create_for_managed_type(Object *p_owner, CSharpScript *p_script, const Ref<MonoGCHandle> &p_gchandle); + static CSharpInstance *create_for_managed_type(Object *p_owner, CSharpScript *p_script, const MonoGCHandleData &p_gchandle); void _call_multilevel(MonoObject *p_mono_object, const StringName &p_method, const Variant **p_args, int p_argcount); - void get_properties_state_for_reloading(List<Pair<StringName, Variant> > &r_state); + void get_properties_state_for_reloading(List<Pair<StringName, Variant>> &r_state); + void get_event_signals_state_for_reloading(List<Pair<StringName, Array>> &r_state); public: MonoObject *get_mono_object() const; @@ -272,11 +286,14 @@ public: void mono_object_disposed(MonoObject *p_obj); /* - * If 'r_delete_owner' is set to true, the caller must memdelete the script instance's owner. Otherwise, if + * If 'r_delete_owner' is set to true, the caller must memdelete the script instance's owner. Otherwise, ifevent_signal * 'r_remove_script_instance' is set to true, the caller must destroy the script instance by removing it from its owner. */ void mono_object_disposed_baseref(MonoObject *p_obj, bool p_is_finalizer, bool &r_delete_owner, bool &r_remove_script_instance); + void connect_event_signals(); + void disconnect_event_signals(); + virtual void refcount_incremented(); virtual bool refcount_decremented(); @@ -301,7 +318,7 @@ public: virtual ScriptLanguage *get_language(); - CSharpInstance(); + CSharpInstance(const Ref<CSharpScript> &p_script); ~CSharpInstance(); }; @@ -309,8 +326,18 @@ struct CSharpScriptBinding { bool inited; StringName type_name; GDMonoClass *wrapper_class; - Ref<MonoGCHandle> gchandle; + MonoGCHandleData gchandle; Object *owner; + + CSharpScriptBinding() : + inited(false), + wrapper_class(NULL), + owner(NULL) { + } +}; + +class ManagedCallableMiddleman : public Object { + GDCLASS(ManagedCallableMiddleman, Object); }; class CSharpLanguage : public ScriptLanguage { @@ -320,9 +347,10 @@ class CSharpLanguage : public ScriptLanguage { static CSharpLanguage *singleton; - bool finalizing; + bool finalizing = false; + bool finalized = false; - GDMono *gdmono; + GDMono *gdmono = nullptr; SelfList<CSharpScript>::List script_list; Mutex script_instances_mutex; @@ -337,6 +365,8 @@ class CSharpLanguage : public ScriptLanguage { Mutex unsafe_object_references_lock; #endif + ManagedCallableMiddleman *managed_callable_middleman = memnew(ManagedCallableMiddleman); + struct StringNameCache { StringName _signal_callback; @@ -348,17 +378,18 @@ class CSharpLanguage : public ScriptLanguage { StringName dotctor; // .ctor StringName on_before_serialize; // OnBeforeSerialize StringName on_after_deserialize; // OnAfterDeserialize + StringName delegate_invoke_method_name; StringNameCache(); }; - int lang_idx; + int lang_idx = -1; Dictionary scripts_metadata; - bool scripts_metadata_invalidated; + bool scripts_metadata_invalidated = true; // For debug_break and debug_break_parse - int _debug_parse_err_line; + int _debug_parse_err_line = -1; String _debug_parse_err_file; String _debug_error; @@ -368,7 +399,7 @@ class CSharpLanguage : public ScriptLanguage { void _on_scripts_domain_unloaded(); #ifdef TOOLS_ENABLED - EditorPlugin *godotsharp_editor; + EditorPlugin *godotsharp_editor = nullptr; static void _editor_init_callback(); #endif @@ -389,8 +420,8 @@ public: _FORCE_INLINE_ EditorPlugin *get_godotsharp_editor() const { return godotsharp_editor; } #endif - static void release_script_gchandle(Ref<MonoGCHandle> &p_gchandle); - static void release_script_gchandle(MonoObject *p_expected_obj, Ref<MonoGCHandle> &p_gchandle); + static void release_script_gchandle(MonoGCHandleData &p_gchandle); + static void release_script_gchandle(MonoObject *p_expected_obj, MonoGCHandleData &p_gchandle); bool debug_break(const String &p_error, bool p_allow_continue = true); bool debug_break_parse(const String &p_file, int p_line, const String &p_error); @@ -410,6 +441,8 @@ public: return scripts_metadata; } + _FORCE_INLINE_ ManagedCallableMiddleman *get_managed_callable_middleman() const { return managed_callable_middleman; } + virtual String get_name() const; /* LANGUAGE FUNCTIONS */ @@ -426,7 +459,7 @@ public: virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const; virtual bool is_using_templates(); virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script); - /* TODO */ virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions, List<ScriptLanguage::Warning> *r_warnings = NULL, Set<int> *r_safe_lines = NULL) const { return true; } + /* TODO */ virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const { return true; } virtual String validate_path(const String &p_path) const; virtual Script *create_script() const; virtual bool has_named_classes() const; @@ -458,7 +491,7 @@ public: virtual void frame(); /* TODO? */ virtual void get_public_functions(List<MethodInfo> *p_functions) const {} - /* TODO? */ virtual void get_public_constants(List<Pair<String, Variant> > *p_constants) const {} + /* TODO? */ virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const {} virtual void reload_all_scripts(); virtual void reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload); @@ -497,7 +530,7 @@ public: class ResourceFormatLoaderCSharpScript : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs index 76cb249acf..9afd9adeb1 100644 --- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs @@ -1,6 +1,8 @@ using GodotTools.Core; using System.Collections.Generic; using System.IO; +using System.Linq; +using System.Text.RegularExpressions; namespace GodotTools.ProjectEditor { @@ -118,5 +120,40 @@ EndProject"; const string ProjectPlatformsConfig = @" {{{0}}}.{1}|Any CPU.ActiveCfg = {1}|Any CPU {{{0}}}.{1}|Any CPU.Build.0 = {1}|Any CPU"; + + public static void MigrateFromOldConfigNames(string slnPath) + { + if (!File.Exists(slnPath)) + return; + + var input = File.ReadAllText(slnPath); + + if (!Regex.IsMatch(input, Regex.Escape("Tools|Any CPU"))) + return; + + // This method renames old configurations in solutions to the new ones. + // + // This is the order configs appear in the solution and what we want to rename them to: + // Debug|Any CPU = Debug|Any CPU -> ExportDebug|Any CPU = ExportDebug|Any CPU + // Tools|Any CPU = Tools|Any CPU -> Debug|Any CPU = Debug|Any CPU + // + // But we want to move Tools (now Debug) to the top, so it's easier to rename like this: + // Debug|Any CPU = Debug|Any CPU -> Debug|Any CPU = Debug|Any CPU + // Release|Any CPU = Release|Any CPU -> ExportDebug|Any CPU = ExportDebug|Any CPU + // Tools|Any CPU = Tools|Any CPU -> ExportRelease|Any CPU = ExportRelease|Any CPU + + var dict = new Dictionary<string, string> + { + {"Debug|Any CPU", "Debug|Any CPU"}, + {"Release|Any CPU", "ExportDebug|Any CPU"}, + {"Tools|Any CPU", "ExportRelease|Any CPU"} + }; + + var regex = new Regex(string.Join("|",dict.Keys.Select(Regex.Escape))); + var result = regex.Replace(input,m => dict[m.Value]); + + if (result != input) + File.WriteAllText(slnPath, result); + } } } diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs index 28b7832f90..cbe3afaedd 100644 --- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs @@ -17,30 +17,30 @@ namespace GodotTools.ProjectEditor string path = Path.Combine(dir, name + ".csproj"); ProjectPropertyGroupElement mainGroup; - var root = CreateLibraryProject(name, "Tools", out mainGroup); + var root = CreateLibraryProject(name, "Debug", out mainGroup); mainGroup.SetProperty("OutputPath", Path.Combine(".mono", "temp", "bin", "$(Configuration)")); mainGroup.SetProperty("BaseIntermediateOutputPath", Path.Combine(".mono", "temp", "obj")); mainGroup.SetProperty("IntermediateOutputPath", Path.Combine("$(BaseIntermediateOutputPath)", "$(Configuration)")); - mainGroup.SetProperty("ApiConfiguration", "Debug").Condition = " '$(Configuration)' != 'Release' "; - mainGroup.SetProperty("ApiConfiguration", "Release").Condition = " '$(Configuration)' == 'Release' "; - - var toolsGroup = root.AddPropertyGroup(); - toolsGroup.Condition = " '$(Configuration)|$(Platform)' == 'Tools|AnyCPU' "; - toolsGroup.AddProperty("DebugSymbols", "true"); - toolsGroup.AddProperty("DebugType", "portable"); - toolsGroup.AddProperty("Optimize", "false"); - toolsGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;DEBUG;TOOLS;"); - toolsGroup.AddProperty("ErrorReport", "prompt"); - toolsGroup.AddProperty("WarningLevel", "4"); - toolsGroup.AddProperty("ConsolePause", "false"); + mainGroup.SetProperty("ApiConfiguration", "Debug").Condition = " '$(Configuration)' != 'ExportRelease' "; + mainGroup.SetProperty("ApiConfiguration", "Release").Condition = " '$(Configuration)' == 'ExportRelease' "; + + var debugGroup = root.AddPropertyGroup(); + debugGroup.Condition = " '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "; + debugGroup.AddProperty("DebugSymbols", "true"); + debugGroup.AddProperty("DebugType", "portable"); + debugGroup.AddProperty("Optimize", "false"); + debugGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;DEBUG;TOOLS;"); + debugGroup.AddProperty("ErrorReport", "prompt"); + debugGroup.AddProperty("WarningLevel", "4"); + debugGroup.AddProperty("ConsolePause", "false"); var coreApiRef = root.AddItem("Reference", CoreApiProjectName); coreApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", "$(ApiConfiguration)", CoreApiProjectName + ".dll")); coreApiRef.AddMetadata("Private", "False"); var editorApiRef = root.AddItem("Reference", EditorApiProjectName); - editorApiRef.Condition = " '$(Configuration)' == 'Tools' "; + editorApiRef.Condition = " '$(Configuration)' == 'Debug' "; editorApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", "$(ApiConfiguration)", EditorApiProjectName + ".dll")); editorApiRef.AddMetadata("Private", "False"); @@ -103,24 +103,24 @@ namespace GodotTools.ProjectEditor mainGroup.AddProperty("TargetFrameworkVersion", "v4.7"); mainGroup.AddProperty("GodotProjectGeneratorVersion", Assembly.GetExecutingAssembly().GetName().Version.ToString()); - var debugGroup = root.AddPropertyGroup(); - debugGroup.Condition = " '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "; - debugGroup.AddProperty("DebugSymbols", "true"); - debugGroup.AddProperty("DebugType", "portable"); - debugGroup.AddProperty("Optimize", "false"); - debugGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;DEBUG;"); - debugGroup.AddProperty("ErrorReport", "prompt"); - debugGroup.AddProperty("WarningLevel", "4"); - debugGroup.AddProperty("ConsolePause", "false"); - - var releaseGroup = root.AddPropertyGroup(); - releaseGroup.Condition = " '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "; - releaseGroup.AddProperty("DebugType", "portable"); - releaseGroup.AddProperty("Optimize", "true"); - releaseGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;"); - releaseGroup.AddProperty("ErrorReport", "prompt"); - releaseGroup.AddProperty("WarningLevel", "4"); - releaseGroup.AddProperty("ConsolePause", "false"); + var exportDebugGroup = root.AddPropertyGroup(); + exportDebugGroup.Condition = " '$(Configuration)|$(Platform)' == 'ExportDebug|AnyCPU' "; + exportDebugGroup.AddProperty("DebugSymbols", "true"); + exportDebugGroup.AddProperty("DebugType", "portable"); + exportDebugGroup.AddProperty("Optimize", "false"); + exportDebugGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;DEBUG;"); + exportDebugGroup.AddProperty("ErrorReport", "prompt"); + exportDebugGroup.AddProperty("WarningLevel", "4"); + exportDebugGroup.AddProperty("ConsolePause", "false"); + + var exportReleaseGroup = root.AddPropertyGroup(); + exportReleaseGroup.Condition = " '$(Configuration)|$(Platform)' == 'ExportRelease|AnyCPU' "; + exportReleaseGroup.AddProperty("DebugType", "portable"); + exportReleaseGroup.AddProperty("Optimize", "true"); + exportReleaseGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;"); + exportReleaseGroup.AddProperty("ErrorReport", "prompt"); + exportReleaseGroup.AddProperty("WarningLevel", "4"); + exportReleaseGroup.AddProperty("ConsolePause", "false"); // References var referenceGroup = root.AddItemGroup(); diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs index 233aab45b3..af36f125f5 100644 --- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using System.Reflection; using DotNet.Globbing; using Microsoft.Build.Construction; @@ -44,6 +45,7 @@ namespace GodotTools.ProjectEditor globOptions.Evaluation.CaseInsensitive = false; var root = ProjectRootElement.Open(projectPath); + Debug.Assert(root != null); foreach (var itemGroup in root.ItemGroups) { @@ -85,35 +87,35 @@ namespace GodotTools.ProjectEditor void AddPropertyIfNotPresent(string name, string condition, string value) { if (root.PropertyGroups - .Any(g => (g.Condition == string.Empty || g.Condition == condition) && + .Any(g => (g.Condition == string.Empty || g.Condition.Trim() == condition) && g.Properties .Any(p => p.Name == name && p.Value == value && - (p.Condition == condition || g.Condition == condition)))) + (p.Condition.Trim() == condition || g.Condition.Trim() == condition)))) { return; } - root.AddProperty(name, value).Condition = condition; + root.AddProperty(name, value).Condition = " " + condition + " "; dirty = true; } AddPropertyIfNotPresent(name: "ApiConfiguration", - condition: " '$(Configuration)' != 'Release' ", + condition: "'$(Configuration)' != 'ExportRelease'", value: "Debug"); AddPropertyIfNotPresent(name: "ApiConfiguration", - condition: " '$(Configuration)' == 'Release' ", + condition: "'$(Configuration)' == 'ExportRelease'", value: "Release"); void SetReferenceHintPath(string referenceName, string condition, string hintPath) { foreach (var itemGroup in root.ItemGroups.Where(g => - g.Condition == string.Empty || g.Condition == condition)) + g.Condition.Trim() == string.Empty || g.Condition.Trim() == condition)) { var references = itemGroup.Items.Where(item => item.ItemType == "Reference" && item.Include == referenceName && - (item.Condition == condition || itemGroup.Condition == condition)); + (item.Condition.Trim() == condition || itemGroup.Condition.Trim() == condition)); var referencesWithHintPath = references.Where(reference => reference.Metadata.Any(m => m.Name == "HintPath")); @@ -152,7 +154,7 @@ namespace GodotTools.ProjectEditor } // Found no Reference item at all. Add it. - root.AddItem("Reference", referenceName).Condition = condition; + root.AddItem("Reference", referenceName).Condition = " " + condition + " "; dirty = true; } @@ -160,7 +162,7 @@ namespace GodotTools.ProjectEditor const string editorProjectName = "GodotSharpEditor"; const string coreCondition = ""; - const string editorCondition = " '$(Configuration)' == 'Tools' "; + const string editorCondition = "'$(Configuration)' == 'Debug'"; var coreHintPath = $"$(ProjectDir)/.mono/assemblies/$(ApiConfiguration)/{coreProjectName}.dll"; var editorHintPath = $"$(ProjectDir)/.mono/assemblies/$(ApiConfiguration)/{editorProjectName}.dll"; @@ -171,5 +173,104 @@ namespace GodotTools.ProjectEditor if (dirty) root.Save(); } + + public static void MigrateFromOldConfigNames(string projectPath) + { + var root = ProjectRootElement.Open(projectPath); + Debug.Assert(root != null); + + bool dirty = false; + + bool hasGodotProjectGeneratorVersion = false; + bool foundOldConfiguration = false; + + foreach (var propertyGroup in root.PropertyGroups.Where(g => g.Condition == string.Empty)) + { + if (!hasGodotProjectGeneratorVersion && propertyGroup.Properties.Any(p => p.Name == "GodotProjectGeneratorVersion")) + hasGodotProjectGeneratorVersion = true; + + foreach (var configItem in propertyGroup.Properties + .Where(p => p.Condition.Trim() == "'$(Configuration)' == ''" && p.Value == "Tools")) + { + configItem.Value = "Debug"; + foundOldConfiguration = true; + dirty = true; + } + } + + if (!hasGodotProjectGeneratorVersion) + { + root.PropertyGroups.First(g => g.Condition == string.Empty)? + .AddProperty("GodotProjectGeneratorVersion", Assembly.GetExecutingAssembly().GetName().Version.ToString()); + dirty = true; + } + + if (!foundOldConfiguration) + { + var toolsConditions = new[] + { + "'$(Configuration)|$(Platform)' == 'Tools|AnyCPU'", + "'$(Configuration)|$(Platform)' != 'Tools|AnyCPU'", + "'$(Configuration)' == 'Tools'", + "'$(Configuration)' != 'Tools'" + }; + + foundOldConfiguration = root.PropertyGroups + .Any(g => toolsConditions.Any(c => c == g.Condition.Trim())); + } + + if (foundOldConfiguration) + { + void MigrateConfigurationConditions(string oldConfiguration, string newConfiguration) + { + void MigrateConditions(string oldCondition, string newCondition) + { + foreach (var propertyGroup in root.PropertyGroups.Where(g => g.Condition.Trim() == oldCondition)) + { + propertyGroup.Condition = " " + newCondition + " "; + dirty = true; + } + + foreach (var propertyGroup in root.PropertyGroups) + { + foreach (var prop in propertyGroup.Properties.Where(p => p.Condition.Trim() == oldCondition)) + { + prop.Condition = " " + newCondition + " "; + dirty = true; + } + } + + foreach (var itemGroup in root.ItemGroups.Where(g => g.Condition.Trim() == oldCondition)) + { + itemGroup.Condition = " " + newCondition + " "; + dirty = true; + } + + foreach (var itemGroup in root.ItemGroups) + { + foreach (var item in itemGroup.Items.Where(item => item.Condition.Trim() == oldCondition)) + { + item.Condition = " " + newCondition + " "; + dirty = true; + } + } + } + + foreach (var op in new[] {"==", "!="}) + { + MigrateConditions($"'$(Configuration)|$(Platform)' {op} '{oldConfiguration}|AnyCPU'", $"'$(Configuration)|$(Platform)' {op} '{newConfiguration}|AnyCPU'"); + MigrateConditions($"'$(Configuration)' {op} '{oldConfiguration}'", $"'$(Configuration)' {op} '{newConfiguration}'"); + } + } + + MigrateConfigurationConditions("Debug", "ExportDebug"); + MigrateConfigurationConditions("Release", "ExportRelease"); + MigrateConfigurationConditions("Tools", "Debug"); // Must be last + } + + + if (dirty) + root.Save(); + } } } diff --git a/modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs b/modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs index bd7eb59913..e4c8759802 100644 --- a/modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs +++ b/modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs @@ -166,7 +166,7 @@ namespace GodotTools Internal.GodotIs32Bits() ? "32" : "64" }; - bool buildSuccess = BuildManager.BuildProjectBlocking("Tools", godotDefines); + bool buildSuccess = BuildManager.BuildProjectBlocking("Debug", godotDefines); if (!buildSuccess) return; @@ -280,7 +280,7 @@ namespace GodotTools Text = "Build Project".TTR(), FocusMode = FocusModeEnum.None }; - buildProjectBtn.Connect("pressed", this, nameof(BuildProjectPressed)); + buildProjectBtn.PressedSignal += BuildProjectPressed; toolBarHBox.AddChild(buildProjectBtn); toolBarHBox.AddSpacer(begin: false); @@ -293,7 +293,7 @@ namespace GodotTools Visible = false, FocusMode = FocusModeEnum.None }; - warningsBtn.Connect("toggled", this, nameof(_WarningsToggled)); + warningsBtn.Toggled += _WarningsToggled; toolBarHBox.AddChild(warningsBtn); errorsBtn = new ToolButton @@ -304,7 +304,7 @@ namespace GodotTools Visible = false, FocusMode = FocusModeEnum.None }; - errorsBtn.Connect("toggled", this, nameof(_ErrorsToggled)); + errorsBtn.Toggled += _ErrorsToggled; toolBarHBox.AddChild(errorsBtn); toolBarHBox.AddSpacer(begin: false); @@ -315,7 +315,7 @@ namespace GodotTools FocusMode = FocusModeEnum.None, Visible = false }; - viewLogBtn.Connect("pressed", this, nameof(_ViewLogPressed)); + viewLogBtn.PressedSignal += _ViewLogPressed; toolBarHBox.AddChild(viewLogBtn); var hsc = new HSplitContainer @@ -326,8 +326,8 @@ namespace GodotTools panelBuildsTab.AddChild(hsc); buildTabsList = new ItemList { SizeFlagsHorizontal = (int)SizeFlags.ExpandFill }; - buildTabsList.Connect("item_selected", this, nameof(_BuildTabsItemSelected)); - buildTabsList.Connect("nothing_selected", this, nameof(_BuildTabsNothingSelected)); + buildTabsList.ItemSelected += _BuildTabsItemSelected; + buildTabsList.NothingSelected += _BuildTabsNothingSelected; hsc.AddChild(buildTabsList); buildTabs = new TabContainer diff --git a/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs b/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs index 69a8c9cf4a..94214cbb8f 100644 --- a/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs +++ b/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs @@ -166,7 +166,7 @@ namespace GodotTools // Make sure the API assemblies are up to date before building the project. // We may not have had the chance to update the release API assemblies, and the debug ones // may have been deleted by the user at some point after they were loaded by the Godot editor. - string apiAssembliesUpdateError = Internal.UpdateApiAssembliesFromPrebuilt(config == "Release" ? "Release" : "Debug"); + string apiAssembliesUpdateError = Internal.UpdateApiAssembliesFromPrebuilt(config == "ExportRelease" ? "Release" : "Debug"); if (!string.IsNullOrEmpty(apiAssembliesUpdateError)) { @@ -242,7 +242,7 @@ namespace GodotTools Internal.GodotIs32Bits() ? "32" : "64" }; - return BuildProjectBlocking("Tools", godotDefines); + return BuildProjectBlocking("Debug", godotDefines); } public static void Initialize() @@ -256,7 +256,7 @@ namespace GodotTools : BuildTool.MsBuildVs; EditorDef("mono/builds/build_tool", msbuild); - + editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary { ["type"] = Godot.Variant.Type.Int, diff --git a/modules/mono/editor/GodotTools/GodotTools/BuildTab.cs b/modules/mono/editor/GodotTools/GodotTools/BuildTab.cs index f75fe239e3..b2459b69ad 100644 --- a/modules/mono/editor/GodotTools/GodotTools/BuildTab.cs +++ b/modules/mono/editor/GodotTools/GodotTools/BuildTab.cs @@ -251,7 +251,7 @@ namespace GodotTools base._Ready(); issuesList = new ItemList { SizeFlagsVertical = (int)SizeFlags.ExpandFill }; - issuesList.Connect("item_activated", this, nameof(_IssueActivated)); + issuesList.ItemActivated += _IssueActivated; AddChild(issuesList); } diff --git a/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs b/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs index 9abfda4538..421729cc11 100644 --- a/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs +++ b/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs @@ -32,18 +32,6 @@ namespace GodotTools ProjectUtils.AddItemToProjectChecked(projectPath, itemType, include); } - public static void FixApiHintPath(string projectPath) - { - try - { - ProjectUtils.FixApiHintPath(projectPath); - } - catch (Exception e) - { - GD.PushError(e.ToString()); - } - } - private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); private static ulong ConvertToTimestamp(this DateTime value) diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs index 3e2a8c22a9..05f84f547b 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs @@ -150,7 +150,7 @@ namespace GodotTools.Export string outputDir = new FileInfo(path).Directory?.FullName ?? throw new FileNotFoundException("Base directory not found"); - string buildConfig = isDebug ? "Debug" : "Release"; + string buildConfig = isDebug ? "ExportDebug" : "ExportRelease"; string scriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, $"scripts_metadata.{(isDebug ? "debug" : "release")}"); CsProjOperations.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, scriptsMetadataPath); diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs index 147bc95bb8..e4e391765e 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs @@ -61,7 +61,7 @@ namespace GodotTools { Guid = guid, PathRelativeToSolution = name + ".csproj", - Configs = new List<string> { "Debug", "Release", "Tools" } + Configs = new List<string> { "Debug", "ExportDebug", "ExportRelease" } }; solution.AddNewProject(name, projectInfo); @@ -121,16 +121,9 @@ namespace GodotTools aboutDialog.PopupCenteredMinsize(); } - private void _ToggleAboutDialogOnStart(bool enabled) + private void _MenuOptionPressed(int id) { - bool showOnStart = (bool)editorSettings.GetSetting("mono/editor/show_info_on_start"); - if (showOnStart != enabled) - editorSettings.SetSetting("mono/editor/show_info_on_start", enabled); - } - - private void _MenuOptionPressed(MenuOptions id) - { - switch (id) + switch ((MenuOptions)id) { case MenuOptions.CreateSln: CreateProjectSolution(); @@ -210,7 +203,7 @@ namespace GodotTools string scriptPath = ProjectSettings.GlobalizePath(script.ResourcePath); RiderPathManager.OpenFile(GodotSharpDirs.ProjectSlnPath, scriptPath, line); return Error.Ok; - } + } case ExternalEditorId.MonoDevelop: { string scriptPath = ProjectSettings.GlobalizePath(script.ResourcePath); @@ -395,14 +388,33 @@ namespace GodotTools // CheckBox in main container aboutDialogCheckBox = new CheckBox { Text = "Show this warning when starting the editor" }; - aboutDialogCheckBox.Connect("toggled", this, nameof(_ToggleAboutDialogOnStart)); + aboutDialogCheckBox.Toggled += enabled => + { + bool showOnStart = (bool)editorSettings.GetSetting("mono/editor/show_info_on_start"); + if (showOnStart != enabled) + editorSettings.SetSetting("mono/editor/show_info_on_start", enabled); + }; aboutVBox.AddChild(aboutDialogCheckBox); } if (File.Exists(GodotSharpDirs.ProjectSlnPath) && File.Exists(GodotSharpDirs.ProjectCsProjPath)) { - // Make sure the existing project has Api assembly references configured correctly - CsProjOperations.FixApiHintPath(GodotSharpDirs.ProjectCsProjPath); + try + { + // Migrate solution from old configuration names to: Debug, ExportDebug and ExportRelease + DotNetSolution.MigrateFromOldConfigNames(GodotSharpDirs.ProjectSlnPath); + // Migrate csproj from old configuration names to: Debug, ExportDebug and ExportRelease + ProjectUtils.MigrateFromOldConfigNames(GodotSharpDirs.ProjectCsProjPath); + + // Apply the other fixes after configurations are migrated + + // Make sure the existing project has Api assembly references configured correctly + ProjectUtils.FixApiHintPath(GodotSharpDirs.ProjectCsProjPath); + } + catch (Exception e) + { + GD.PushError(e.ToString()); + } } else { @@ -410,7 +422,7 @@ namespace GodotTools menuPopup.AddItem("Create C# solution".TTR(), (int)MenuOptions.CreateSln); } - menuPopup.Connect("id_pressed", this, nameof(_MenuOptionPressed)); + menuPopup.IdPressed += _MenuOptionPressed; var buildButton = new ToolButton { @@ -418,7 +430,7 @@ namespace GodotTools HintTooltip = "Build solution", FocusMode = Control.FocusModeEnum.None }; - buildButton.Connect("pressed", this, nameof(_BuildSolutionPressed)); + buildButton.PressedSignal += _BuildSolutionPressed; AddControlToContainer(CustomControlContainer.Toolbar, buildButton); // External editor settings diff --git a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs index 0ed567afd1..1d19fab706 100644 --- a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs +++ b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs @@ -40,7 +40,7 @@ namespace GodotTools OneShot = false, WaitTime = (float)EditorDef("mono/assembly_watch_interval_sec", 0.5) }; - watchTimer.Connect("timeout", this, nameof(TimerTimeout)); + watchTimer.Timeout += TimerTimeout; AddChild(watchTimer); watchTimer.Start(); } diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 908c72c591..9a5de6db16 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -76,7 +76,7 @@ #define GLUE_HEADER_FILE "glue_header.h" #define ICALL_PREFIX "godot_icall_" #define SINGLETON_ICALL_SUFFIX "_get_singleton" -#define ICALL_GET_METHODBIND ICALL_PREFIX "Object_ClassDB_get_method" +#define ICALL_GET_METHODBIND "__ClassDB_get_method" #define C_LOCAL_RET "ret" #define C_LOCAL_VARARG_RET "vararg_ret" @@ -95,6 +95,10 @@ #define C_METHOD_MONOSTR_FROM_GODOT C_NS_MONOMARSHAL "::mono_string_from_godot" #define C_METHOD_MONOARRAY_TO(m_type) C_NS_MONOMARSHAL "::mono_array_to_" #m_type #define C_METHOD_MONOARRAY_FROM(m_type) C_NS_MONOMARSHAL "::" #m_type "_to_mono_array" +#define C_METHOD_MANAGED_TO_CALLABLE C_NS_MONOMARSHAL "::managed_to_callable" +#define C_METHOD_MANAGED_FROM_CALLABLE C_NS_MONOMARSHAL "::callable_to_managed" +#define C_METHOD_MANAGED_TO_SIGNAL C_NS_MONOMARSHAL "::signal_info_to_callable" +#define C_METHOD_MANAGED_FROM_SIGNAL C_NS_MONOMARSHAL "::callable_to_signal_info" #define BINDINGS_GENERATOR_VERSION UINT32_C(11) @@ -504,23 +508,23 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf xml_output.append(tag); xml_output.append("</c>"); } else if (tag == "PackedByteArray") { - xml_output.append("<see cref=\"byte\"/>"); + xml_output.append("<see cref=\"T:byte[]\"/>"); } else if (tag == "PackedInt32Array") { - xml_output.append("<see cref=\"int\"/>"); + xml_output.append("<see cref=\"T:int[]\"/>"); + } else if (tag == "PackedInt64Array") { + xml_output.append("<see cref=\"T:long[]\"/>"); } else if (tag == "PackedFloat32Array") { -#ifdef REAL_T_IS_DOUBLE - xml_output.append("<see cref=\"double\"/>"); -#else - xml_output.append("<see cref=\"float\"/>"); -#endif + xml_output.append("<see cref=\"T:float[]\"/>"); + } else if (tag == "PackedFloat64Array") { + xml_output.append("<see cref=\"T:double[]\"/>"); } else if (tag == "PackedStringArray") { - xml_output.append("<see cref=\"string\"/>"); + xml_output.append("<see cref=\"T:string[]\"/>"); } else if (tag == "PackedVector2Array") { - xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".Vector2\"/>"); + xml_output.append("<see cref=\"T:" BINDINGS_NAMESPACE ".Vector2[]\"/>"); } else if (tag == "PackedVector3Array") { - xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".Vector3\"/>"); + xml_output.append("<see cref=\"T:" BINDINGS_NAMESPACE ".Vector3[]\"/>"); } else if (tag == "PackedColorArray") { - xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".Color\"/>"); + xml_output.append("<see cref=\"T:" BINDINGS_NAMESPACE ".Color[]\"/>"); } else { const TypeInterface *target_itype = _get_type_or_null(TypeReference(tag)); @@ -932,7 +936,7 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) { "using System.Runtime.CompilerServices;\n" "\n"); cs_icalls_content.append("namespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK); - cs_icalls_content.append(INDENT1 "internal static class " BINDINGS_CLASS_NATIVECALLS "\n" INDENT1 OPEN_BLOCK); + cs_icalls_content.append(INDENT1 "internal static class " BINDINGS_CLASS_NATIVECALLS "\n" INDENT1 "{"); cs_icalls_content.append(MEMBER_BEGIN "internal static ulong godot_api_hash = "); cs_icalls_content.append(String::num_uint64(GDMono::get_singleton()->get_api_core_hash()) + ";\n"); @@ -944,7 +948,7 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) { #define ADD_INTERNAL_CALL(m_icall) \ if (!m_icall.editor_only) { \ cs_icalls_content.append(MEMBER_BEGIN "[MethodImpl(MethodImplOptions.InternalCall)]\n"); \ - cs_icalls_content.append(INDENT2 "internal extern static "); \ + cs_icalls_content.append(INDENT2 "internal static extern "); \ cs_icalls_content.append(m_icall.im_type_out + " "); \ cs_icalls_content.append(m_icall.name + "("); \ cs_icalls_content.append(m_icall.im_sig + ");\n"); \ @@ -1046,7 +1050,7 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir) { #define ADD_INTERNAL_CALL(m_icall) \ if (m_icall.editor_only) { \ cs_icalls_content.append(INDENT2 "[MethodImpl(MethodImplOptions.InternalCall)]\n"); \ - cs_icalls_content.append(INDENT2 "internal extern static "); \ + cs_icalls_content.append(INDENT2 "internal static extern "); \ cs_icalls_content.append(m_icall.im_type_out + " "); \ cs_icalls_content.append(m_icall.name + "("); \ cs_icalls_content.append(m_icall.im_sig + ");\n"); \ @@ -1312,7 +1316,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str output.append(itype.proxy_name); output.append(").Name);\n" INDENT4 "return singleton;\n" INDENT3 "}\n" INDENT2 "}\n"); - output.append(MEMBER_BEGIN "private const string " BINDINGS_NATIVE_NAME_FIELD " = \""); + output.append(MEMBER_BEGIN "private static StringName " BINDINGS_NATIVE_NAME_FIELD " = \""); output.append(itype.name); output.append("\";\n"); @@ -1324,7 +1328,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str } else if (is_derived_type) { // Add member fields - output.append(MEMBER_BEGIN "private const string " BINDINGS_NATIVE_NAME_FIELD " = \""); + output.append(MEMBER_BEGIN "private static StringName " BINDINGS_NATIVE_NAME_FIELD " = \""); output.append(itype.name); output.append("\";\n"); @@ -1363,6 +1367,13 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str "Failed to generate method '" + imethod.name + "' for class '" + itype.name + "'."); } + for (const List<SignalInterface>::Element *E = itype.signals_.front(); E; E = E->next()) { + const SignalInterface &isignal = E->get(); + Error method_err = _generate_cs_signal(itype, isignal, output); + ERR_FAIL_COND_V_MSG(method_err != OK, method_err, + "Failed to generate signal '" + isignal.name + "' for class '" + itype.name + "'."); + } + if (itype.is_singleton) { InternalCall singleton_icall = InternalCall(itype.api_type, ICALL_PREFIX + itype.name + SINGLETON_ICALL_SUFFIX, "IntPtr"); @@ -1424,7 +1435,16 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte } if (getter && setter) { - ERR_FAIL_COND_V(getter->return_type.cname != setter->arguments.back()->get().type.cname, ERR_BUG); + const ArgumentInterface &setter_first_arg = setter->arguments.back()->get(); + if (getter->return_type.cname != setter_first_arg.type.cname) { + // Special case for Node::set_name + bool whitelisted = getter->return_type.cname == name_cache.type_StringName && + setter_first_arg.type.cname == name_cache.type_String; + + ERR_FAIL_COND_V_MSG(!whitelisted, ERR_BUG, + "Return type from getter doesn't match first argument of setter for property: '" + + p_itype.name + "." + String(p_iprop.cname) + "'."); + } } const TypeReference &proptype_name = getter ? getter->return_type : setter->arguments.back()->get().type; @@ -1525,7 +1545,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf const TypeInterface *return_type = _get_type_or_placeholder(p_imethod.return_type); - String method_bind_field = "method_bind_" + itos(p_method_bind_count); + String method_bind_field = "__method_bind_" + itos(p_method_bind_count); String arguments_sig; String cs_in_statements; @@ -1612,7 +1632,8 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf { if (!p_imethod.is_virtual && !p_imethod.requires_object_call) { p_output.append(MEMBER_BEGIN "[DebuggerBrowsable(DebuggerBrowsableState.Never)]" MEMBER_BEGIN "private static IntPtr "); - p_output.append(method_bind_field + " = Object." ICALL_GET_METHODBIND "(" BINDINGS_NATIVE_NAME_FIELD ", \""); + p_output.append(method_bind_field); + p_output.append(" = Object." ICALL_GET_METHODBIND "(" BINDINGS_NATIVE_NAME_FIELD ", \""); p_output.append(p_imethod.name); p_output.append("\");\n"); } @@ -1726,6 +1747,106 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf return OK; } +Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::SignalInterface &p_isignal, StringBuilder &p_output) { + String arguments_sig; + + // Retrieve information from the arguments + for (const List<ArgumentInterface>::Element *F = p_isignal.arguments.front(); F; F = F->next()) { + const ArgumentInterface &iarg = F->get(); + const TypeInterface *arg_type = _get_type_or_placeholder(iarg.type); + + // Add the current arguments to the signature + + if (F != p_isignal.arguments.front()) + arguments_sig += ", "; + + arguments_sig += arg_type->cs_type; + arguments_sig += " "; + arguments_sig += iarg.name; + } + + // Generate signal + { + if (p_isignal.method_doc && p_isignal.method_doc->description.size()) { + String xml_summary = bbcode_to_xml(fix_doc_description(p_isignal.method_doc->description), &p_itype); + Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>(); + + if (summary_lines.size()) { + p_output.append(MEMBER_BEGIN "/// <summary>\n"); + + for (int i = 0; i < summary_lines.size(); i++) { + p_output.append(INDENT2 "/// "); + p_output.append(summary_lines[i]); + p_output.append("\n"); + } + + p_output.append(INDENT2 "/// </summary>"); + } + } + + if (p_isignal.is_deprecated) { + if (p_isignal.deprecation_message.empty()) + WARN_PRINT("An empty deprecation message is discouraged. Signal: '" + p_isignal.proxy_name + "'."); + + p_output.append(MEMBER_BEGIN "[Obsolete(\""); + p_output.append(p_isignal.deprecation_message); + p_output.append("\")]"); + } + + String delegate_name = p_isignal.proxy_name; + delegate_name += "Handler"; // Delegate name is [SignalName]Handler + + // Generate delegate + p_output.append(MEMBER_BEGIN "public delegate void "); + p_output.append(delegate_name); + p_output.append("("); + p_output.append(arguments_sig); + p_output.append(");\n"); + + // TODO: + // Could we assume the StringName instance of signal name will never be freed (it's stored in ClassDB) before the managed world is unloaded? + // If so, we could store the pointer we get from `data_unique_pointer()` instead of allocating StringName here. + + // Cached signal name (StringName) + p_output.append(MEMBER_BEGIN "[DebuggerBrowsable(DebuggerBrowsableState.Never)]" MEMBER_BEGIN "private static StringName __signal_name_"); + p_output.append(p_isignal.name); + p_output.append(" = \""); + p_output.append(p_isignal.name); + p_output.append("\";\n"); + + // Generate event + p_output.append(MEMBER_BEGIN "[Signal]" MEMBER_BEGIN "public "); + + if (p_itype.is_singleton) + p_output.append("static "); + + p_output.append("event "); + p_output.append(delegate_name); + p_output.append(" "); + p_output.append(p_isignal.proxy_name); + p_output.append("\n" OPEN_BLOCK_L2); + + if (p_itype.is_singleton) + p_output.append("add => Singleton.Connect(__signal_name_"); + else + p_output.append("add => Connect(__signal_name_"); + + p_output.append(p_isignal.name); + p_output.append(", new Callable(value));\n"); + + if (p_itype.is_singleton) + p_output.append(INDENT3 "remove => Singleton.Disconnect(__signal_name_"); + else + p_output.append(INDENT3 "remove => Disconnect(__signal_name_"); + + p_output.append(p_isignal.name); + p_output.append(", new Callable(value));\n"); + p_output.append(CLOSE_BLOCK_L2); + } + + return OK; +} + Error BindingsGenerator::generate_glue(const String &p_output_dir) { ERR_FAIL_COND_V(!initialized, ERR_UNCONFIGURED); @@ -2479,13 +2600,92 @@ bool BindingsGenerator::_populate_object_type_interfaces() { } } + // Populate signals + + const HashMap<StringName, MethodInfo> &signal_map = class_info->signal_map; + const StringName *k = NULL; + + while ((k = signal_map.next(k))) { + SignalInterface isignal; + + const MethodInfo &method_info = signal_map.get(*k); + + isignal.name = method_info.name; + isignal.cname = method_info.name; + + int argc = method_info.arguments.size(); + + for (int i = 0; i < argc; i++) { + PropertyInfo arginfo = method_info.arguments[i]; + + String orig_arg_name = arginfo.name; + + ArgumentInterface iarg; + iarg.name = orig_arg_name; + + if (arginfo.type == Variant::INT && arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { + iarg.type.cname = arginfo.class_name; + iarg.type.is_enum = true; + } else if (arginfo.class_name != StringName()) { + iarg.type.cname = arginfo.class_name; + } else if (arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { + iarg.type.cname = arginfo.hint_string; + } else if (arginfo.type == Variant::NIL) { + iarg.type.cname = name_cache.type_Variant; + } else { + if (arginfo.type == Variant::INT) { + iarg.type.cname = _get_int_type_name_from_meta(GodotTypeInfo::METADATA_NONE); + } else if (arginfo.type == Variant::FLOAT) { + iarg.type.cname = _get_float_type_name_from_meta(GodotTypeInfo::METADATA_NONE); + } else { + iarg.type.cname = Variant::get_type_name(arginfo.type); + } + } + + iarg.name = escape_csharp_keyword(snake_to_camel_case(iarg.name)); + + isignal.add_argument(iarg); + } + + isignal.proxy_name = escape_csharp_keyword(snake_to_pascal_case(isignal.name)); + + // Prevent the signal and its enclosing type from sharing the same name + if (isignal.proxy_name == itype.proxy_name) { + _log("Name of signal '%s' is ambiguous with the name of its enclosing class '%s'. Renaming signal to '%s_'\n", + isignal.proxy_name.utf8().get_data(), itype.proxy_name.utf8().get_data(), isignal.proxy_name.utf8().get_data()); + + isignal.proxy_name += "_"; + } + + if (itype.find_property_by_proxy_name(isignal.proxy_name) || itype.find_method_by_proxy_name(isignal.proxy_name)) { + // ClassDB allows signal names that conflict with method or property names. + // While registering a signal with a conflicting name is considered wrong, + // it may still happen and it may take some time until someone fixes the name. + // We can't allow the bindings to be in a broken state while we wait for a fix; + // that's why we must handle this possibility by renaming the signal. + isignal.proxy_name += "Signal"; + } + + if (itype.class_doc) { + for (int i = 0; i < itype.class_doc->signals.size(); i++) { + const DocData::MethodDoc &signal_doc = itype.class_doc->signals[i]; + if (signal_doc.name == isignal.name) { + isignal.method_doc = &signal_doc; + break; + } + } + } + + itype.signals_.push_back(isignal); + } + // Populate enums and constants List<String> constants; ClassDB::get_integer_constant_list(type_cname, &constants, true); - const HashMap<StringName, List<StringName> > &enum_map = class_info->enum_map; - const StringName *k = NULL; + const HashMap<StringName, List<StringName>> &enum_map = class_info->enum_map; + k = NULL; while ((k = enum_map.next(k))) { StringName enum_proxy_cname = *k; @@ -2587,8 +2787,15 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar #endif break; case Variant::STRING: + case Variant::STRING_NAME: case Variant::NODE_PATH: - r_iarg.default_argument = "\"" + r_iarg.default_argument + "\""; + if (r_iarg.type.cname == name_cache.type_StringName || r_iarg.type.cname == name_cache.type_NodePath) { + r_iarg.default_argument = "(%s)\"" + r_iarg.default_argument + "\""; + r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF; + } else { + CRASH_COND(r_iarg.type.cname != name_cache.type_String); + r_iarg.default_argument = "\"" + r_iarg.default_argument + "\""; + } break; case Variant::TRANSFORM: if (p_val.operator Transform() == Transform()) @@ -2603,8 +2810,11 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; break; case Variant::VECTOR2: + case Variant::VECTOR2I: case Variant::RECT2: + case Variant::RECT2I: case Variant::VECTOR3: + case Variant::VECTOR3I: r_iarg.default_argument = "new %s" + r_iarg.default_argument; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; break; @@ -2630,8 +2840,8 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar case Variant::ARRAY: case Variant::PACKED_BYTE_ARRAY: case Variant::PACKED_INT32_ARRAY: - case Variant::PACKED_FLOAT32_ARRAY: case Variant::PACKED_INT64_ARRAY: + case Variant::PACKED_FLOAT32_ARRAY: case Variant::PACKED_FLOAT64_ARRAY: case Variant::PACKED_STRING_ARRAY: case Variant::PACKED_VECTOR2_ARRAY: @@ -2646,8 +2856,13 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar r_iarg.default_argument = Variant::get_type_name(p_val.get_type()) + ".Identity"; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; break; - default: { - } + case Variant::CALLABLE: + case Variant::SIGNAL: + CRASH_NOW_MSG("Parameter of type '" + String(r_iarg.type.cname) + "' cannot have a default value."); + break; + default: + CRASH_NOW_MSG("Unexpected Variant type: " + itos(p_val.get_type())); + break; } if (r_iarg.def_param_mode == ArgumentInterface::CONSTANT && r_iarg.type.cname == name_cache.type_Variant && r_iarg.default_argument != "null") @@ -2672,16 +2887,19 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.c_type_out = "GDMonoMarshal::M_" #m_type; \ itype.cs_in = "ref %s"; \ /* in cs_out, im_type_out (%3) includes the 'out ' part */ \ - itype.cs_out = "%0(%1, %3 argRet); return (%2)argRet;"; \ + itype.cs_out = "%0(%1, %3 argRet); return argRet;"; \ itype.im_type_out = "out " + itype.cs_type; \ itype.ret_as_byref_arg = true; \ builtin_types.insert(itype.cname, itype); \ } INSERT_STRUCT_TYPE(Vector2) + INSERT_STRUCT_TYPE(Vector2i) INSERT_STRUCT_TYPE(Rect2) + INSERT_STRUCT_TYPE(Rect2i) INSERT_STRUCT_TYPE(Transform2D) INSERT_STRUCT_TYPE(Vector3) + INSERT_STRUCT_TYPE(Vector3i) INSERT_STRUCT_TYPE(Basis) INSERT_STRUCT_TYPE(Quat) INSERT_STRUCT_TYPE(Transform) @@ -2749,7 +2967,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.im_type_out = "out " + itype.name; itype.cs_in = "ref %0"; /* in cs_out, im_type_out (%3) includes the 'out ' part */ - itype.cs_out = "%0(%1, %3 argRet); return (%2)argRet;"; + itype.cs_out = "%0(%1, %3 argRet); return argRet;"; itype.ret_as_byref_arg = true; builtin_types.insert(itype.cname, itype); @@ -2766,7 +2984,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.im_type_out = "out " + itype.name; itype.cs_in = "ref %0"; /* in cs_out, im_type_out (%3) includes the 'out ' part */ - itype.cs_out = "%0(%1, %3 argRet); return (%2)argRet;"; + itype.cs_out = "%0(%1, %3 argRet); return argRet;"; itype.ret_as_byref_arg = true; builtin_types.insert(itype.cname, itype); } @@ -2792,7 +3010,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.im_type_out = "out " + itype.proxy_name; itype.cs_in = "ref %0"; /* in cs_out, im_type_out (%3) includes the 'out ' part */ - itype.cs_out = "%0(%1, %3 argRet); return (%2)argRet;"; + itype.cs_out = "%0(%1, %3 argRet); return argRet;"; itype.ret_as_byref_arg = true; builtin_types.insert(itype.cname, itype); @@ -2814,7 +3032,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.im_type_out = "out " + itype.proxy_name; itype.cs_in = "ref %0"; /* in cs_out, im_type_out (%3) includes the 'out ' part */ - itype.cs_out = "%0(%1, %3 argRet); return (%2)argRet;"; + itype.cs_out = "%0(%1, %3 argRet); return argRet;"; itype.ret_as_byref_arg = true; builtin_types.insert(itype.cname, itype); } @@ -2835,6 +3053,24 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.im_type_out = itype.proxy_name; builtin_types.insert(itype.cname, itype); + // StringName + itype = TypeInterface(); + itype.name = "StringName"; + itype.cname = itype.name; + itype.proxy_name = "StringName"; + itype.c_in = "\t%0 %1_in = %1 ? *%1 : StringName();\n"; + itype.c_out = "\treturn memnew(StringName(%1));\n"; + itype.c_arg_in = "&%s_in"; + itype.c_type = itype.name; + itype.c_type_in = itype.c_type + "*"; + itype.c_type_out = itype.c_type + "*"; + itype.cs_type = itype.proxy_name; + itype.cs_in = "StringName." CS_SMETHOD_GETINSTANCE "(%0)"; + itype.cs_out = "return new %2(%0(%1));"; + itype.im_type_in = "IntPtr"; + itype.im_type_out = "IntPtr"; + builtin_types.insert(itype.cname, itype); + // NodePath itype = TypeInterface(); itype.name = "NodePath"; @@ -2883,6 +3119,40 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.im_type_out = itype.proxy_name; builtin_types.insert(itype.cname, itype); + // Callable + itype = TypeInterface::create_value_type(String("Callable")); + itype.c_in = "\t%0 %1_in = " C_METHOD_MANAGED_TO_CALLABLE "(*%1);\n"; + itype.c_out = "\t*%3 = " C_METHOD_MANAGED_FROM_CALLABLE "(%1);\n"; + itype.c_arg_in = "&%s_in"; + itype.c_type_in = "GDMonoMarshal::M_Callable*"; + itype.c_type_out = "GDMonoMarshal::M_Callable"; + itype.cs_in = "ref %s"; + /* in cs_out, im_type_out (%3) includes the 'out ' part */ + itype.cs_out = "%0(%1, %3 argRet); return argRet;"; + itype.im_type_out = "out " + itype.cs_type; + itype.ret_as_byref_arg = true; + builtin_types.insert(itype.cname, itype); + + // Signal + itype = TypeInterface(); + itype.name = "Signal"; + itype.cname = itype.name; + itype.proxy_name = "SignalInfo"; + itype.c_in = "\t%0 %1_in = " C_METHOD_MANAGED_TO_SIGNAL "(*%1);\n"; + itype.c_out = "\t*%3 = " C_METHOD_MANAGED_FROM_SIGNAL "(%1);\n"; + itype.c_arg_in = "&%s_in"; + itype.c_type = itype.name; + itype.c_type_in = "GDMonoMarshal::M_SignalInfo*"; + itype.c_type_out = "GDMonoMarshal::M_SignalInfo"; + itype.cs_in = "ref %s"; + /* in cs_out, im_type_out (%3) includes the 'out ' part */ + itype.cs_out = "%0(%1, %3 argRet); return argRet;"; + itype.cs_type = itype.proxy_name; + itype.im_type_in = "ref " + itype.cs_type; + itype.im_type_out = "out " + itype.cs_type; + itype.ret_as_byref_arg = true; + builtin_types.insert(itype.cname, itype); + // VarArg (fictitious type to represent variable arguments) itype = TypeInterface(); itype.name = "VarArg"; @@ -2917,13 +3187,11 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { #define INSERT_ARRAY(m_type, m_proxy_t) INSERT_ARRAY_FULL(m_type, m_type, m_proxy_t) INSERT_ARRAY(PackedInt32Array, int); + INSERT_ARRAY(PackedInt64Array, long); INSERT_ARRAY_FULL(PackedByteArray, PackedByteArray, byte); -#ifdef REAL_T_IS_DOUBLE - INSERT_ARRAY(PackedFloat32Array, double); -#else INSERT_ARRAY(PackedFloat32Array, float); -#endif + INSERT_ARRAY(PackedFloat64Array, double); INSERT_ARRAY(PackedStringArray, string); @@ -3052,7 +3320,10 @@ void BindingsGenerator::_populate_global_constants() { // HARDCODED List<StringName> hardcoded_enums; + hardcoded_enums.push_back("Vector2.Axis"); + hardcoded_enums.push_back("Vector2i.Axis"); hardcoded_enums.push_back("Vector3.Axis"); + hardcoded_enums.push_back("Vector3i.Axis"); for (List<StringName>::Element *E = hardcoded_enums.front(); E; E = E->next()) { // These enums are not generated and must be written manually (e.g.: Vector3.Axis) // Here, we assume core types do not begin with underscore diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index d3a8937313..b133923c25 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -107,9 +107,15 @@ class BindingsGenerator { TypeReference type; String name; - String default_argument; DefaultParamMode def_param_mode; + /** + * Determines the expression for the parameter default value. + * Formatting elements: + * %0 or %s: [cs_type] of the argument type + */ + String default_argument; + ArgumentInterface() { def_param_mode = CONSTANT; } @@ -175,6 +181,32 @@ class BindingsGenerator { } }; + struct SignalInterface { + String name; + StringName cname; + + /** + * Name of the C# method + */ + String proxy_name; + + List<ArgumentInterface> arguments; + + const DocData::MethodDoc *method_doc; + + bool is_deprecated; + String deprecation_message; + + void add_argument(const ArgumentInterface &argument) { + arguments.push_back(argument); + } + + SignalInterface() { + method_doc = NULL; + is_deprecated = false; + } + }; + struct TypeInterface { /** * Identifier name for this type. @@ -336,6 +368,7 @@ class BindingsGenerator { List<EnumInterface> enums; List<PropertyInterface> properties; List<MethodInterface> methods; + List<SignalInterface> signals_; const MethodInterface *find_method_by_name(const StringName &p_cname) const { for (const List<MethodInterface>::Element *E = methods.front(); E; E = E->next()) { @@ -364,6 +397,15 @@ class BindingsGenerator { return NULL; } + const MethodInterface *find_method_by_proxy_name(const String &p_proxy_name) const { + for (const List<MethodInterface>::Element *E = methods.front(); E; E = E->next()) { + if (E->get().proxy_name == p_proxy_name) + return &E->get(); + } + + return NULL; + } + private: static void _init_value_type(TypeInterface &itype) { itype.proxy_name = itype.name; @@ -510,7 +552,7 @@ class BindingsGenerator { List<InternalCall> core_custom_icalls; List<InternalCall> editor_custom_icalls; - Map<StringName, List<StringName> > blacklisted_methods; + Map<StringName, List<StringName>> blacklisted_methods; void _initialize_blacklisted_methods(); @@ -524,6 +566,8 @@ class BindingsGenerator { StringName type_Reference; StringName type_RID; StringName type_String; + StringName type_StringName; + StringName type_NodePath; StringName type_at_GlobalScope; StringName enum_Error; @@ -548,6 +592,8 @@ class BindingsGenerator { type_Reference = StaticCString::create("Reference"); type_RID = StaticCString::create("RID"); type_String = StaticCString::create("String"); + type_StringName = StaticCString::create("StringName"); + type_NodePath = StaticCString::create("NodePath"); type_at_GlobalScope = StaticCString::create("@GlobalScope"); enum_Error = StaticCString::create("Error"); @@ -623,6 +669,7 @@ class BindingsGenerator { Error _generate_cs_property(const TypeInterface &p_itype, const PropertyInterface &p_iprop, StringBuilder &p_output); Error _generate_cs_method(const TypeInterface &p_itype, const MethodInterface &p_imethod, int &p_method_bind_count, StringBuilder &p_output); + Error _generate_cs_signal(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::SignalInterface &p_isignal, StringBuilder &p_output); void _generate_global_constants(StringBuilder &p_output); diff --git a/modules/mono/glue/GodotSharp/GodotSharp.sln b/modules/mono/glue/GodotSharp/GodotSharp.sln index a496e36da3..4896d0a07d 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp.sln +++ b/modules/mono/glue/GodotSharp/GodotSharp.sln @@ -8,8 +8,6 @@ Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {AEBF0036-DA76-4341-B651-A3F2856AB2FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs index 3957387be9..39d5782db8 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs @@ -2,7 +2,7 @@ using System; namespace Godot { - [AttributeUsage(AttributeTargets.Delegate)] + [AttributeUsage(AttributeTargets.Delegate | AttributeTargets.Event)] public class SignalAttribute : Attribute { } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs new file mode 100644 index 0000000000..c85cc1884c --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs @@ -0,0 +1,31 @@ +using System; + +namespace Godot +{ + public struct Callable + { + private readonly Object _target; + private readonly StringName _method; + private readonly Delegate _delegate; + + public Object Target => _target; + public StringName Method => _method; + public Delegate Delegate => _delegate; + + public static implicit operator Callable(Delegate @delegate) => new Callable(@delegate); + + public Callable(Object target, StringName method) + { + _target = target; + _method = method; + _delegate = null; + } + + public Callable(Delegate @delegate) + { + _target = null; + _method = null; + _delegate = @delegate; + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs new file mode 100644 index 0000000000..785e87a043 --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs @@ -0,0 +1,395 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Runtime.CompilerServices; + +namespace Godot +{ + internal static class DelegateUtils + { + private enum TargetKind : uint + { + Static, + GodotObject, + CompilerGenerated + } + + internal static bool TrySerializeDelegate(Delegate @delegate, Collections.Array serializedData) + { + if (@delegate is MulticastDelegate multicastDelegate) + { + bool someDelegatesSerialized = false; + + Delegate[] invocationList = multicastDelegate.GetInvocationList(); + + if (invocationList.Length > 1) + { + var multiCastData = new Collections.Array(); + + foreach (Delegate oneDelegate in invocationList) + someDelegatesSerialized |= TrySerializeDelegate(oneDelegate, multiCastData); + + if (!someDelegatesSerialized) + return false; + + serializedData.Add(multiCastData); + return true; + } + } + + if (TrySerializeSingleDelegate(@delegate, out byte[] buffer)) + { + serializedData.Add(buffer); + return true; + } + + return false; + } + + private static bool TrySerializeSingleDelegate(Delegate @delegate, out byte[] buffer) + { + buffer = null; + + object target = @delegate.Target; + + switch (target) + { + case null: + { + using (var stream = new MemoryStream()) + using (var writer = new BinaryWriter(stream)) + { + writer.Write((ulong) TargetKind.Static); + + SerializeType(writer, @delegate.GetType()); + + if (!TrySerializeMethodInfo(writer, @delegate.Method)) + return false; + + buffer = stream.ToArray(); + return true; + } + } + case Godot.Object godotObject: + { + using (var stream = new MemoryStream()) + using (var writer = new BinaryWriter(stream)) + { + writer.Write((ulong) TargetKind.GodotObject); + writer.Write((ulong) godotObject.GetInstanceId()); + + SerializeType(writer, @delegate.GetType()); + + if (!TrySerializeMethodInfo(writer, @delegate.Method)) + return false; + + buffer = stream.ToArray(); + return true; + } + } + default: + { + Type targetType = target.GetType(); + + if (targetType.GetCustomAttribute(typeof(CompilerGeneratedAttribute), true) != null) + { + // Compiler generated. Probably a closure. Try to serialize it. + + using (var stream = new MemoryStream()) + using (var writer = new BinaryWriter(stream)) + { + writer.Write((ulong) TargetKind.CompilerGenerated); + SerializeType(writer, targetType); + + SerializeType(writer, @delegate.GetType()); + + if (!TrySerializeMethodInfo(writer, @delegate.Method)) + return false; + + FieldInfo[] fields = targetType.GetFields(BindingFlags.Instance | BindingFlags.Public); + + writer.Write(fields.Length); + + foreach (FieldInfo field in fields) + { + Type fieldType = field.GetType(); + + Variant.Type variantType = GD.TypeToVariantType(fieldType); + + if (variantType == Variant.Type.Nil) + return false; + + writer.Write(field.Name); + byte[] valueBuffer = GD.Var2Bytes(field.GetValue(target)); + writer.Write(valueBuffer.Length); + writer.Write(valueBuffer); + } + + buffer = stream.ToArray(); + return true; + } + } + + return false; + } + } + } + + private static bool TrySerializeMethodInfo(BinaryWriter writer, MethodInfo methodInfo) + { + if (methodInfo == null) + return false; + + SerializeType(writer, methodInfo.DeclaringType); + + writer.Write(methodInfo.Name); + + int flags = 0; + + if (methodInfo.IsPublic) + flags |= (int) BindingFlags.Public; + else + flags |= (int) BindingFlags.NonPublic; + + if (methodInfo.IsStatic) + flags |= (int) BindingFlags.Static; + else + flags |= (int) BindingFlags.Instance; + + writer.Write(flags); + + Type returnType = methodInfo.ReturnType; + bool hasReturn = methodInfo.ReturnType != typeof(void); + + writer.Write(hasReturn); + if (hasReturn) + SerializeType(writer, returnType); + + ParameterInfo[] parameters = methodInfo.GetParameters(); + + writer.Write(parameters.Length); + + if (parameters.Length > 0) + { + for (int i = 0; i < parameters.Length; i++) + SerializeType(writer, parameters[i].ParameterType); + } + + return true; + } + + private static void SerializeType(BinaryWriter writer, Type type) + { + if (type == null) + { + int genericArgumentsCount = -1; + writer.Write(genericArgumentsCount); + } + else if (type.IsGenericType) + { + Type genericTypeDef = type.GetGenericTypeDefinition(); + Type[] genericArgs = type.GetGenericArguments(); + + int genericArgumentsCount = genericArgs.Length; + writer.Write(genericArgumentsCount); + + string assemblyQualifiedName = genericTypeDef.AssemblyQualifiedName; + Debug.Assert(assemblyQualifiedName != null); + writer.Write(assemblyQualifiedName); + + for (int i = 0; i < genericArgs.Length; i++) + SerializeType(writer, genericArgs[i]); + } + else + { + int genericArgumentsCount = 0; + writer.Write(genericArgumentsCount); + + string assemblyQualifiedName = type.AssemblyQualifiedName; + Debug.Assert(assemblyQualifiedName != null); + writer.Write(assemblyQualifiedName); + } + } + + private static bool TryDeserializeDelegate(Collections.Array serializedData, out Delegate @delegate) + { + if (serializedData.Count == 1) + { + object elem = serializedData[0]; + + if (elem is Collections.Array multiCastData) + return TryDeserializeDelegate(multiCastData, out @delegate); + + return TryDeserializeSingleDelegate((byte[])elem, out @delegate); + } + + @delegate = null; + + var delegates = new List<Delegate>(serializedData.Count); + + foreach (object elem in serializedData) + { + if (elem is Collections.Array multiCastData) + { + if (TryDeserializeDelegate(multiCastData, out Delegate oneDelegate)) + delegates.Add(oneDelegate); + } + else + { + if (TryDeserializeSingleDelegate((byte[]) elem, out Delegate oneDelegate)) + delegates.Add(oneDelegate); + } + } + + if (delegates.Count <= 0) + return false; + + @delegate = delegates.Count == 1 ? delegates[0] : Delegate.Combine(delegates.ToArray()); + return true; + } + + private static bool TryDeserializeSingleDelegate(byte[] buffer, out Delegate @delegate) + { + @delegate = null; + + using (var stream = new MemoryStream(buffer, writable: false)) + using (var reader = new BinaryReader(stream)) + { + var targetKind = (TargetKind) reader.ReadUInt64(); + + switch (targetKind) + { + case TargetKind.Static: + { + Type delegateType = DeserializeType(reader); + if (delegateType == null) + return false; + + if (!TryDeserializeMethodInfo(reader, out MethodInfo methodInfo)) + return false; + + @delegate = Delegate.CreateDelegate(delegateType, null, methodInfo); + return true; + } + case TargetKind.GodotObject: + { + ulong objectId = reader.ReadUInt64(); + Godot.Object godotObject = GD.InstanceFromId(objectId); + if (godotObject == null) + return false; + + Type delegateType = DeserializeType(reader); + if (delegateType == null) + return false; + + if (!TryDeserializeMethodInfo(reader, out MethodInfo methodInfo)) + return false; + + @delegate = Delegate.CreateDelegate(delegateType, godotObject, methodInfo); + return true; + } + case TargetKind.CompilerGenerated: + { + Type targetType = DeserializeType(reader); + if (targetType == null) + return false; + + Type delegateType = DeserializeType(reader); + if (delegateType == null) + return false; + + if (!TryDeserializeMethodInfo(reader, out MethodInfo methodInfo)) + return false; + + int fieldCount = reader.ReadInt32(); + + object recreatedTarget = Activator.CreateInstance(targetType); + + for (int i = 0; i < fieldCount; i++) + { + string name = reader.ReadString(); + int valueBufferLength = reader.ReadInt32(); + byte[] valueBuffer = reader.ReadBytes(valueBufferLength); + + FieldInfo fieldInfo = targetType.GetField(name, BindingFlags.Instance | BindingFlags.Public); + fieldInfo?.SetValue(recreatedTarget, GD.Bytes2Var(valueBuffer)); + } + + @delegate = Delegate.CreateDelegate(delegateType, recreatedTarget, methodInfo); + return true; + } + default: + return false; + } + } + } + + private static bool TryDeserializeMethodInfo(BinaryReader reader, out MethodInfo methodInfo) + { + methodInfo = null; + + Type declaringType = DeserializeType(reader); + + string methodName = reader.ReadString(); + + int flags = reader.ReadInt32(); + + bool hasReturn = reader.ReadBoolean(); + Type returnType = hasReturn ? DeserializeType(reader) : typeof(void); + + int parametersCount = reader.ReadInt32(); + + if (parametersCount > 0) + { + var parameterTypes = new Type[parametersCount]; + + for (int i = 0; i < parametersCount; i++) + { + Type parameterType = DeserializeType(reader); + if (parameterType == null) + return false; + parameterTypes[i] = parameterType; + } + + methodInfo = declaringType.GetMethod(methodName, (BindingFlags) flags, null, parameterTypes, null); + return methodInfo != null && methodInfo.ReturnType == returnType; + } + + methodInfo = declaringType.GetMethod(methodName, (BindingFlags) flags); + return methodInfo != null && methodInfo.ReturnType == returnType; + } + + private static Type DeserializeType(BinaryReader reader) + { + int genericArgumentsCount = reader.ReadInt32(); + + if (genericArgumentsCount == -1) + return null; + + string assemblyQualifiedName = reader.ReadString(); + var type = Type.GetType(assemblyQualifiedName); + + if (type == null) + return null; // Type not found + + if (genericArgumentsCount != 0) + { + var genericArgumentTypes = new Type[genericArgumentsCount]; + + for (int i = 0; i < genericArgumentsCount; i++) + { + Type genericArgumentType = DeserializeType(reader); + if (genericArgumentType == null) + return null; + genericArgumentTypes[i] = genericArgumentType; + } + + type = type.MakeGenericType(genericArgumentTypes); + } + + return type; + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs index 2a9c2d73b1..9384da0e48 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs @@ -5,6 +5,7 @@ using System.Runtime.CompilerServices; using real_t = System.Double; #else using real_t = System.Single; + #endif // TODO: Add comments describing what this class does. It is not obvious. @@ -13,9 +14,9 @@ namespace Godot { public static partial class GD { - public static object Bytes2Var(byte[] bytes, bool allow_objects = false) + public static object Bytes2Var(byte[] bytes, bool allowObjects = false) { - return godot_icall_GD_bytes2var(bytes, allow_objects); + return godot_icall_GD_bytes2var(bytes, allowObjects); } public static object Convert(object what, Variant.Type type) @@ -25,7 +26,7 @@ namespace Godot public static real_t Db2Linear(real_t db) { - return (real_t)Math.Exp(db * 0.11512925464970228420089957273422); + return (real_t) Math.Exp(db * 0.11512925464970228420089957273422); } public static real_t DecTime(real_t value, real_t amount, real_t step) @@ -38,11 +39,11 @@ namespace Godot return val * sgn; } - public static FuncRef FuncRef(Object instance, string funcname) + public static FuncRef FuncRef(Object instance, StringName funcName) { var ret = new FuncRef(); ret.SetInstance(instance); - ret.SetFunction(funcname); + ret.SetFunction(funcName); return ret; } @@ -58,7 +59,7 @@ namespace Godot public static real_t Linear2Db(real_t linear) { - return (real_t)(Math.Log(linear) * 8.6858896380650365530225783783321); + return (real_t) (Math.Log(linear) * 8.6858896380650365530225783783321); } public static Resource Load(string path) @@ -181,14 +182,14 @@ namespace Godot return godot_icall_GD_str2var(str); } - public static bool TypeExists(string type) + public static bool TypeExists(StringName type) { - return godot_icall_GD_type_exists(type); + return godot_icall_GD_type_exists(StringName.GetPtr(type)); } - public static byte[] Var2Bytes(object var, bool full_objects = false) + public static byte[] Var2Bytes(object var, bool fullObjects = false) { - return godot_icall_GD_var2bytes(var, full_objects); + return godot_icall_GD_var2bytes(var, fullObjects); } public static string Var2Str(object var) @@ -196,8 +197,13 @@ namespace Godot return godot_icall_GD_var2str(var); } + public static Variant.Type TypeToVariantType(Type type) + { + return godot_icall_TypeToVariantType(type); + } + [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static object godot_icall_GD_bytes2var(byte[] bytes, bool allow_objects); + internal extern static object godot_icall_GD_bytes2var(byte[] bytes, bool allowObjects); [MethodImpl(MethodImplOptions.InternalCall)] internal extern static object godot_icall_GD_convert(object what, Variant.Type type); @@ -206,7 +212,7 @@ namespace Godot internal extern static int godot_icall_GD_hash(object var); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static Object godot_icall_GD_instance_from_id(ulong instance_id); + internal extern static Object godot_icall_GD_instance_from_id(ulong instanceId); [MethodImpl(MethodImplOptions.InternalCall)] internal extern static void godot_icall_GD_print(object[] what); @@ -249,10 +255,10 @@ namespace Godot internal extern static object godot_icall_GD_str2var(string str); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static bool godot_icall_GD_type_exists(string type); + internal extern static bool godot_icall_GD_type_exists(IntPtr type); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static byte[] godot_icall_GD_var2bytes(object what, bool full_objects); + internal extern static byte[] godot_icall_GD_var2bytes(object what, bool fullObjects); [MethodImpl(MethodImplOptions.InternalCall)] internal extern static string godot_icall_GD_var2str(object var); @@ -262,5 +268,8 @@ namespace Godot [MethodImpl(MethodImplOptions.InternalCall)] internal extern static void godot_icall_GD_pushwarning(string type); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern Variant.Type godot_icall_TypeToVariantType(Type type); } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs index 8c5872ba5a..4ecc55f94e 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs @@ -7,7 +7,7 @@ namespace Godot { private bool disposed = false; - internal IntPtr ptr; + private IntPtr ptr; internal static IntPtr GetPtr(NodePath instance) { @@ -50,104 +50,93 @@ namespace Godot this.ptr = ptr; } - public IntPtr NativeInstance - { - get { return ptr; } - } - public NodePath() : this(string.Empty) {} public NodePath(string path) { - this.ptr = godot_icall_NodePath_Ctor(path); + ptr = godot_icall_NodePath_Ctor(path); } - public static implicit operator NodePath(string from) - { - return new NodePath(from); - } + public static implicit operator NodePath(string from) => new NodePath(from); - public static implicit operator string(NodePath from) - { - return godot_icall_NodePath_operator_String(NodePath.GetPtr(from)); - } + public static implicit operator string(NodePath from) => from.ToString(); public override string ToString() { - return (string)this; + return godot_icall_NodePath_operator_String(GetPtr(this)); } public NodePath GetAsPropertyPath() { - return new NodePath(godot_icall_NodePath_get_as_property_path(NodePath.GetPtr(this))); + return new NodePath(godot_icall_NodePath_get_as_property_path(GetPtr(this))); } public string GetConcatenatedSubnames() { - return godot_icall_NodePath_get_concatenated_subnames(NodePath.GetPtr(this)); + return godot_icall_NodePath_get_concatenated_subnames(GetPtr(this)); } public string GetName(int idx) { - return godot_icall_NodePath_get_name(NodePath.GetPtr(this), idx); + return godot_icall_NodePath_get_name(GetPtr(this), idx); } public int GetNameCount() { - return godot_icall_NodePath_get_name_count(NodePath.GetPtr(this)); + return godot_icall_NodePath_get_name_count(GetPtr(this)); } public string GetSubname(int idx) { - return godot_icall_NodePath_get_subname(NodePath.GetPtr(this), idx); + return godot_icall_NodePath_get_subname(GetPtr(this), idx); } public int GetSubnameCount() { - return godot_icall_NodePath_get_subname_count(NodePath.GetPtr(this)); + return godot_icall_NodePath_get_subname_count(GetPtr(this)); } public bool IsAbsolute() { - return godot_icall_NodePath_is_absolute(NodePath.GetPtr(this)); + return godot_icall_NodePath_is_absolute(GetPtr(this)); } public bool IsEmpty() { - return godot_icall_NodePath_is_empty(NodePath.GetPtr(this)); + return godot_icall_NodePath_is_empty(GetPtr(this)); } [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static IntPtr godot_icall_NodePath_Ctor(string path); + private static extern IntPtr godot_icall_NodePath_Ctor(string path); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static void godot_icall_NodePath_Dtor(IntPtr ptr); + private static extern void godot_icall_NodePath_Dtor(IntPtr ptr); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static string godot_icall_NodePath_operator_String(IntPtr ptr); + private static extern string godot_icall_NodePath_operator_String(IntPtr ptr); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static IntPtr godot_icall_NodePath_get_as_property_path(IntPtr ptr); + private static extern IntPtr godot_icall_NodePath_get_as_property_path(IntPtr ptr); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static string godot_icall_NodePath_get_concatenated_subnames(IntPtr ptr); + private static extern string godot_icall_NodePath_get_concatenated_subnames(IntPtr ptr); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static string godot_icall_NodePath_get_name(IntPtr ptr, int arg1); + private static extern string godot_icall_NodePath_get_name(IntPtr ptr, int arg1); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static int godot_icall_NodePath_get_name_count(IntPtr ptr); + private static extern int godot_icall_NodePath_get_name_count(IntPtr ptr); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static string godot_icall_NodePath_get_subname(IntPtr ptr, int arg1); + private static extern string godot_icall_NodePath_get_subname(IntPtr ptr, int arg1); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static int godot_icall_NodePath_get_subname_count(IntPtr ptr); + private static extern int godot_icall_NodePath_get_subname_count(IntPtr ptr); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static bool godot_icall_NodePath_is_absolute(IntPtr ptr); + private static extern bool godot_icall_NodePath_is_absolute(IntPtr ptr); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static bool godot_icall_NodePath_is_empty(IntPtr ptr); + private static extern bool godot_icall_NodePath_is_empty(IntPtr ptr); } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs index de80f7fddc..42610c5ef7 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs @@ -7,7 +7,7 @@ namespace Godot { private bool disposed = false; - private const string nativeName = "Object"; + private static StringName nativeName = "Object"; internal IntPtr ptr; internal bool memoryOwn; @@ -15,7 +15,14 @@ namespace Godot public Object() : this(false) { if (ptr == IntPtr.Zero) + { ptr = godot_icall_Object_Ctor(this); + } + else + { + // This is called inside godot_icall_Object_Ctor, so we must call it as well in this case. + godot_icall_Object_ConnectEventSignals(ptr); + } } internal Object(bool memoryOwn) @@ -101,7 +108,7 @@ namespace Godot /// } /// </code> /// </example> - public SignalAwaiter ToSignal(Object source, string signal) + public SignalAwaiter ToSignal(Object source, StringName signal) { return new SignalAwaiter(source, signal, this); } @@ -111,20 +118,28 @@ namespace Godot /// </summary> public dynamic DynamicObject => new DynamicGodotObject(this); + internal static IntPtr __ClassDB_get_method(StringName type, string method) + { + return godot_icall_Object_ClassDB_get_method(StringName.GetPtr(type), method); + } + + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern IntPtr godot_icall_Object_Ctor(Object obj); + [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static IntPtr godot_icall_Object_Ctor(Object obj); + internal static extern void godot_icall_Object_Disposed(Object obj, IntPtr ptr); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static void godot_icall_Object_Disposed(Object obj, IntPtr ptr); + internal static extern void godot_icall_Reference_Disposed(Object obj, IntPtr ptr, bool isFinalizer); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static void godot_icall_Reference_Disposed(Object obj, IntPtr ptr, bool isFinalizer); + internal static extern void godot_icall_Object_ConnectEventSignals(IntPtr obj); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static string godot_icall_Object_ToString(IntPtr ptr); + internal static extern string godot_icall_Object_ToString(IntPtr ptr); // Used by the generated API [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static IntPtr godot_icall_Object_ClassDB_get_method(string type, string method); + internal static extern IntPtr godot_icall_Object_ClassDB_get_method(IntPtr type, string method); } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs new file mode 100644 index 0000000000..bc2cad8713 --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs @@ -0,0 +1,262 @@ +using System; +using System.Runtime.InteropServices; + +namespace Godot +{ + [Serializable] + [StructLayout(LayoutKind.Sequential)] + public struct Rect2i : IEquatable<Rect2i> + { + private Vector2i _position; + private Vector2i _size; + + public Vector2i Position + { + get { return _position; } + set { _position = value; } + } + + public Vector2i Size + { + get { return _size; } + set { _size = value; } + } + + public Vector2i End + { + get { return _position + _size; } + set { _size = value - _position; } + } + + public int Area + { + get { return GetArea(); } + } + + public Rect2i Abs() + { + Vector2i end = End; + Vector2i topLeft = new Vector2i(Mathf.Min(_position.x, end.x), Mathf.Min(_position.y, end.y)); + return new Rect2i(topLeft, _size.Abs()); + } + + public Rect2i Clip(Rect2i b) + { + var newRect = b; + + if (!Intersects(newRect)) + return new Rect2i(); + + newRect._position.x = Mathf.Max(b._position.x, _position.x); + newRect._position.y = Mathf.Max(b._position.y, _position.y); + + Vector2i bEnd = b._position + b._size; + Vector2i end = _position + _size; + + newRect._size.x = Mathf.Min(bEnd.x, end.x) - newRect._position.x; + newRect._size.y = Mathf.Min(bEnd.y, end.y) - newRect._position.y; + + return newRect; + } + + public bool Encloses(Rect2i b) + { + return b._position.x >= _position.x && b._position.y >= _position.y && + b._position.x + b._size.x < _position.x + _size.x && + b._position.y + b._size.y < _position.y + _size.y; + } + + public Rect2i Expand(Vector2i to) + { + var expanded = this; + + Vector2i begin = expanded._position; + Vector2i end = expanded._position + expanded._size; + + if (to.x < begin.x) + begin.x = to.x; + if (to.y < begin.y) + begin.y = to.y; + + if (to.x > end.x) + end.x = to.x; + if (to.y > end.y) + end.y = to.y; + + expanded._position = begin; + expanded._size = end - begin; + + return expanded; + } + + public int GetArea() + { + return _size.x * _size.y; + } + + public Rect2i Grow(int by) + { + var g = this; + + g._position.x -= by; + g._position.y -= by; + g._size.x += by * 2; + g._size.y += by * 2; + + return g; + } + + public Rect2i GrowIndividual(int left, int top, int right, int bottom) + { + var g = this; + + g._position.x -= left; + g._position.y -= top; + g._size.x += left + right; + g._size.y += top + bottom; + + return g; + } + + public Rect2i GrowMargin(Margin margin, int by) + { + var g = this; + + g.GrowIndividual(Margin.Left == margin ? by : 0, + Margin.Top == margin ? by : 0, + Margin.Right == margin ? by : 0, + Margin.Bottom == margin ? by : 0); + + return g; + } + + public bool HasNoArea() + { + return _size.x <= 0 || _size.y <= 0; + } + + public bool HasPoint(Vector2i point) + { + if (point.x < _position.x) + return false; + if (point.y < _position.y) + return false; + + if (point.x >= _position.x + _size.x) + return false; + if (point.y >= _position.y + _size.y) + return false; + + return true; + } + + public bool Intersects(Rect2i b) + { + if (_position.x >= b._position.x + b._size.x) + return false; + if (_position.x + _size.x <= b._position.x) + return false; + if (_position.y >= b._position.y + b._size.y) + return false; + if (_position.y + _size.y <= b._position.y) + return false; + + return true; + } + + public Rect2i Merge(Rect2i b) + { + Rect2i newRect; + + newRect._position.x = Mathf.Min(b._position.x, _position.x); + newRect._position.y = Mathf.Min(b._position.y, _position.y); + + newRect._size.x = Mathf.Max(b._position.x + b._size.x, _position.x + _size.x); + newRect._size.y = Mathf.Max(b._position.y + b._size.y, _position.y + _size.y); + + newRect._size = newRect._size - newRect._position; // Make relative again + + return newRect; + } + + // Constructors + public Rect2i(Vector2i position, Vector2i size) + { + _position = position; + _size = size; + } + public Rect2i(Vector2i position, int width, int height) + { + _position = position; + _size = new Vector2i(width, height); + } + public Rect2i(int x, int y, Vector2i size) + { + _position = new Vector2i(x, y); + _size = size; + } + public Rect2i(int x, int y, int width, int height) + { + _position = new Vector2i(x, y); + _size = new Vector2i(width, height); + } + + public static bool operator ==(Rect2i left, Rect2i right) + { + return left.Equals(right); + } + + public static bool operator !=(Rect2i left, Rect2i right) + { + return !left.Equals(right); + } + + public static implicit operator Rect2(Rect2i value) + { + return new Rect2(value._position, value._size); + } + + public static explicit operator Rect2i(Rect2 value) + { + return new Rect2i((Vector2i)value.Position, (Vector2i)value.Size); + } + + public override bool Equals(object obj) + { + if (obj is Rect2i) + { + return Equals((Rect2i)obj); + } + + return false; + } + + public bool Equals(Rect2i other) + { + return _position.Equals(other._position) && _size.Equals(other._size); + } + + public override int GetHashCode() + { + return _position.GetHashCode() ^ _size.GetHashCode(); + } + + public override string ToString() + { + return String.Format("{0}, {1}", new object[] + { + _position.ToString(), + _size.ToString() + }); + } + + public string ToString(string format) + { + return String.Format("{0}, {1}", new object[] + { + _position.ToString(format), + _size.ToString(format) + }); + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs index 9483b6ffb4..4dc630238b 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs @@ -9,13 +9,13 @@ namespace Godot private object[] result; private Action action; - public SignalAwaiter(Object source, string signal, Object target) + public SignalAwaiter(Object source, StringName signal, Object target) { - godot_icall_SignalAwaiter_connect(Object.GetPtr(source), signal, Object.GetPtr(target), this); + godot_icall_SignalAwaiter_connect(Object.GetPtr(source), StringName.GetPtr(signal), Object.GetPtr(target), this); } [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static Error godot_icall_SignalAwaiter_connect(IntPtr source, string signal, IntPtr target, SignalAwaiter awaiter); + internal extern static Error godot_icall_SignalAwaiter_connect(IntPtr source, IntPtr signal, IntPtr target, SignalAwaiter awaiter); public bool IsCompleted { @@ -50,11 +50,5 @@ namespace Godot action(); } } - - internal void FailureCallback() - { - action = null; - completed = true; - } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs new file mode 100644 index 0000000000..dc92de7a61 --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs @@ -0,0 +1,17 @@ +namespace Godot +{ + public struct SignalInfo + { + private readonly Object _owner; + private readonly StringName _signalName; + + public Object Owner => _owner; + public StringName Name => _signalName; + + public SignalInfo(Object owner, StringName name) + { + _owner = owner; + _signalName = name; + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs new file mode 100644 index 0000000000..7700b6d4ed --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs @@ -0,0 +1,82 @@ +using System; +using System.Runtime.CompilerServices; + +namespace Godot +{ + public sealed partial class StringName : IDisposable + { + private IntPtr ptr; + + internal static IntPtr GetPtr(StringName instance) + { + if (instance == null) + throw new NullReferenceException($"The instance of type {nameof(StringName)} is null."); + + if (instance.ptr == IntPtr.Zero) + throw new ObjectDisposedException(instance.GetType().FullName); + + return instance.ptr; + } + + ~StringName() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (ptr != IntPtr.Zero) + { + godot_icall_StringName_Dtor(ptr); + ptr = IntPtr.Zero; + } + } + + internal StringName(IntPtr ptr) + { + this.ptr = ptr; + } + + public StringName() + { + ptr = IntPtr.Zero; + } + + public StringName(string path) + { + ptr = path == null ? IntPtr.Zero : godot_icall_StringName_Ctor(path); + } + + public static implicit operator StringName(string from) => new StringName(from); + + public static implicit operator string(StringName from) => from.ToString(); + + public override string ToString() + { + return ptr == IntPtr.Zero ? string.Empty : godot_icall_StringName_operator_String(GetPtr(this)); + } + + public bool IsEmpty() + { + return ptr == IntPtr.Zero || godot_icall_StringName_is_empty(GetPtr(this)); + } + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern IntPtr godot_icall_StringName_Ctor(string path); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern void godot_icall_StringName_Dtor(IntPtr ptr); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string godot_icall_StringName_operator_String(IntPtr ptr); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern bool godot_icall_StringName_is_empty(IntPtr ptr); + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs index 385bfed122..f7b13198f8 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs @@ -76,11 +76,6 @@ namespace Godot } } - public real_t Cross(Vector2 b) - { - return x * b.y - y * b.x; - } - public Vector2 Abs() { return new Vector2(Mathf.Abs(x), Mathf.Abs(y)); @@ -130,6 +125,11 @@ namespace Godot return v; } + public real_t Cross(Vector2 b) + { + return x * b.y - y * b.x; + } + public Vector2 CubicInterpolate(Vector2 b, Vector2 preA, Vector2 postB, real_t t) { var p0 = preA; @@ -234,7 +234,7 @@ namespace Godot public Vector2 Reflect(Vector2 n) { - return 2.0f * n * Dot(n) - this; + return 2 * Dot(n) * n - this; } public Vector2 Rotated(real_t phi) @@ -352,18 +352,18 @@ namespace Godot return left; } - public static Vector2 operator /(Vector2 vec, real_t scale) + public static Vector2 operator /(Vector2 vec, real_t divisor) { - vec.x /= scale; - vec.y /= scale; + vec.x /= divisor; + vec.y /= divisor; return vec; } - public static Vector2 operator /(Vector2 left, Vector2 right) + public static Vector2 operator /(Vector2 vec, Vector2 divisorv) { - left.x /= right.x; - left.y /= right.y; - return left; + vec.x /= divisorv.x; + vec.y /= divisorv.y; + return vec; } public static Vector2 operator %(Vector2 vec, real_t divisor) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs new file mode 100644 index 0000000000..7dc22d7918 --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs @@ -0,0 +1,380 @@ +using System; +using System.Runtime.InteropServices; + +#if REAL_T_IS_DOUBLE +using real_t = System.Double; +#else +using real_t = System.Single; +#endif + +namespace Godot +{ + /// <summary> + /// 2-element structure that can be used to represent 2D grid coordinates or pairs of integers. + /// </summary> + [Serializable] + [StructLayout(LayoutKind.Sequential)] + public struct Vector2i : IEquatable<Vector2i> + { + public enum Axis + { + X = 0, + Y + } + + public int x; + public int y; + + public int this[int index] + { + get + { + switch (index) + { + case 0: + return x; + case 1: + return y; + default: + throw new IndexOutOfRangeException(); + } + } + set + { + switch (index) + { + case 0: + x = value; + return; + case 1: + y = value; + return; + default: + throw new IndexOutOfRangeException(); + } + } + } + + public Vector2i Abs() + { + return new Vector2i(Mathf.Abs(x), Mathf.Abs(y)); + } + + public real_t Angle() + { + return Mathf.Atan2(y, x); + } + + public real_t AngleTo(Vector2i to) + { + return Mathf.Atan2(Cross(to), Dot(to)); + } + + public real_t AngleToPoint(Vector2i to) + { + return Mathf.Atan2(y - to.y, x - to.x); + } + + public real_t Aspect() + { + return x / (real_t)y; + } + + public Vector2i Bounce(Vector2i n) + { + return -Reflect(n); + } + + public int Cross(Vector2i b) + { + return x * b.y - y * b.x; + } + + public int DistanceSquaredTo(Vector2i b) + { + return (b - this).LengthSquared(); + } + + public real_t DistanceTo(Vector2i b) + { + return (b - this).Length(); + } + + public int Dot(Vector2i b) + { + return x * b.x + y * b.y; + } + + public real_t Length() + { + int x2 = x * x; + int y2 = y * y; + + return Mathf.Sqrt(x2 + y2); + } + + public int LengthSquared() + { + int x2 = x * x; + int y2 = y * y; + + return x2 + y2; + } + + public Axis MaxAxis() + { + return x < y ? Axis.Y : Axis.X; + } + + public Axis MinAxis() + { + return x > y ? Axis.Y : Axis.X; + } + + public Vector2i PosMod(int mod) + { + Vector2i v = this; + v.x = Mathf.PosMod(v.x, mod); + v.y = Mathf.PosMod(v.y, mod); + return v; + } + + public Vector2i PosMod(Vector2i modv) + { + Vector2i v = this; + v.x = Mathf.PosMod(v.x, modv.x); + v.y = Mathf.PosMod(v.y, modv.y); + return v; + } + + public Vector2i Reflect(Vector2i n) + { + return 2 * Dot(n) * n - this; + } + + public Vector2i Sign() + { + Vector2i v = this; + v.x = Mathf.Sign(v.x); + v.y = Mathf.Sign(v.y); + return v; + } + + public Vector2i Tangent() + { + return new Vector2i(y, -x); + } + + // Constants + private static readonly Vector2i _zero = new Vector2i(0, 0); + private static readonly Vector2i _one = new Vector2i(1, 1); + + private static readonly Vector2i _up = new Vector2i(0, -1); + private static readonly Vector2i _down = new Vector2i(0, 1); + private static readonly Vector2i _right = new Vector2i(1, 0); + private static readonly Vector2i _left = new Vector2i(-1, 0); + + public static Vector2i Zero { get { return _zero; } } + public static Vector2i One { get { return _one; } } + + public static Vector2i Up { get { return _up; } } + public static Vector2i Down { get { return _down; } } + public static Vector2i Right { get { return _right; } } + public static Vector2i Left { get { return _left; } } + + // Constructors + public Vector2i(int x, int y) + { + this.x = x; + this.y = y; + } + public Vector2i(Vector2i vi) + { + this.x = vi.x; + this.y = vi.y; + } + public Vector2i(Vector2 v) + { + this.x = Mathf.RoundToInt(v.x); + this.y = Mathf.RoundToInt(v.y); + } + + public static Vector2i operator +(Vector2i left, Vector2i right) + { + left.x += right.x; + left.y += right.y; + return left; + } + + public static Vector2i operator -(Vector2i left, Vector2i right) + { + left.x -= right.x; + left.y -= right.y; + return left; + } + + public static Vector2i operator -(Vector2i vec) + { + vec.x = -vec.x; + vec.y = -vec.y; + return vec; + } + + public static Vector2i operator *(Vector2i vec, int scale) + { + vec.x *= scale; + vec.y *= scale; + return vec; + } + + public static Vector2i operator *(int scale, Vector2i vec) + { + vec.x *= scale; + vec.y *= scale; + return vec; + } + + public static Vector2i operator *(Vector2i left, Vector2i right) + { + left.x *= right.x; + left.y *= right.y; + return left; + } + + public static Vector2i operator /(Vector2i vec, int divisor) + { + vec.x /= divisor; + vec.y /= divisor; + return vec; + } + + public static Vector2i operator /(Vector2i vec, Vector2i divisorv) + { + vec.x /= divisorv.x; + vec.y /= divisorv.y; + return vec; + } + + public static Vector2i operator %(Vector2i vec, int divisor) + { + vec.x %= divisor; + vec.y %= divisor; + return vec; + } + + public static Vector2i operator %(Vector2i vec, Vector2i divisorv) + { + vec.x %= divisorv.x; + vec.y %= divisorv.y; + return vec; + } + + public static Vector2i operator &(Vector2i vec, int and) + { + vec.x &= and; + vec.y &= and; + return vec; + } + + public static Vector2i operator &(Vector2i vec, Vector2i andv) + { + vec.x &= andv.x; + vec.y &= andv.y; + return vec; + } + + public static bool operator ==(Vector2i left, Vector2i right) + { + return left.Equals(right); + } + + public static bool operator !=(Vector2i left, Vector2i right) + { + return !left.Equals(right); + } + + public static bool operator <(Vector2i left, Vector2i right) + { + if (left.x.Equals(right.x)) + { + return left.y < right.y; + } + return left.x < right.x; + } + + public static bool operator >(Vector2i left, Vector2i right) + { + if (left.x.Equals(right.x)) + { + return left.y > right.y; + } + return left.x > right.x; + } + + public static bool operator <=(Vector2i left, Vector2i right) + { + if (left.x.Equals(right.x)) + { + return left.y <= right.y; + } + return left.x <= right.x; + } + + public static bool operator >=(Vector2i left, Vector2i right) + { + if (left.x.Equals(right.x)) + { + return left.y >= right.y; + } + return left.x >= right.x; + } + + public static implicit operator Vector2(Vector2i value) + { + return new Vector2(value.x, value.y); + } + + public static explicit operator Vector2i(Vector2 value) + { + return new Vector2i(value); + } + + public override bool Equals(object obj) + { + if (obj is Vector2i) + { + return Equals((Vector2i)obj); + } + + return false; + } + + public bool Equals(Vector2i other) + { + return x == other.x && y == other.y; + } + + public override int GetHashCode() + { + return y.GetHashCode() ^ x.GetHashCode(); + } + + public override string ToString() + { + return String.Format("({0}, {1})", new object[] + { + this.x.ToString(), + this.y.ToString() + }); + } + + public string ToString(string format) + { + return String.Format("({0}, {1})", new object[] + { + this.x.ToString(format), + this.y.ToString(format) + }); + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs index 390036c654..a43836e985 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -400,20 +400,20 @@ namespace Godot return left; } - public static Vector3 operator /(Vector3 vec, real_t scale) + public static Vector3 operator /(Vector3 vec, real_t divisor) { - vec.x /= scale; - vec.y /= scale; - vec.z /= scale; + vec.x /= divisor; + vec.y /= divisor; + vec.z /= divisor; return vec; } - public static Vector3 operator /(Vector3 left, Vector3 right) + public static Vector3 operator /(Vector3 vec, Vector3 divisorv) { - left.x /= right.x; - left.y /= right.y; - left.z /= right.z; - return left; + vec.x /= divisorv.x; + vec.y /= divisorv.y; + vec.z /= divisorv.z; + return vec; } public static Vector3 operator %(Vector3 vec, real_t divisor) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs new file mode 100644 index 0000000000..c17f900131 --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs @@ -0,0 +1,402 @@ +using System; +using System.Runtime.InteropServices; + +#if REAL_T_IS_DOUBLE +using real_t = System.Double; +#else +using real_t = System.Single; +#endif + +namespace Godot +{ + /// <summary> + /// 3-element structure that can be used to represent 3D grid coordinates or sets of integers. + /// </summary> + [Serializable] + [StructLayout(LayoutKind.Sequential)] + public struct Vector3i : IEquatable<Vector3i> + { + public enum Axis + { + X = 0, + Y, + Z + } + + public int x; + public int y; + public int z; + + public int this[int index] + { + get + { + switch (index) + { + case 0: + return x; + case 1: + return y; + case 2: + return z; + default: + throw new IndexOutOfRangeException(); + } + } + set + { + switch (index) + { + case 0: + x = value; + return; + case 1: + y = value; + return; + case 2: + z = value; + return; + default: + throw new IndexOutOfRangeException(); + } + } + } + + public Vector3i Abs() + { + Vector3i v = this; + if (v.x < 0) + { + v.x = -v.x; + } + if (v.y < 0) + { + v.y = -v.y; + } + if (v.z < 0) + { + v.z = -v.z; + } + return v; + } + + public int DistanceSquaredTo(Vector3i b) + { + return (b - this).LengthSquared(); + } + + public real_t DistanceTo(Vector3i b) + { + return (b - this).Length(); + } + + public int Dot(Vector3i b) + { + return x * b.x + y * b.y + z * b.z; + } + + public real_t Length() + { + int x2 = x * x; + int y2 = y * y; + int z2 = z * z; + + return Mathf.Sqrt(x2 + y2 + z2); + } + + public int LengthSquared() + { + int x2 = x * x; + int y2 = y * y; + int z2 = z * z; + + return x2 + y2 + z2; + } + + public Axis MaxAxis() + { + return x < y ? (y < z ? Axis.Z : Axis.Y) : (x < z ? Axis.Z : Axis.X); + } + + public Axis MinAxis() + { + return x < y ? (x < z ? Axis.X : Axis.Z) : (y < z ? Axis.Y : Axis.Z); + } + + public Vector3i PosMod(int mod) + { + Vector3i v = this; + v.x = Mathf.PosMod(v.x, mod); + v.y = Mathf.PosMod(v.y, mod); + v.z = Mathf.PosMod(v.z, mod); + return v; + } + + public Vector3i PosMod(Vector3i modv) + { + Vector3i v = this; + v.x = Mathf.PosMod(v.x, modv.x); + v.y = Mathf.PosMod(v.y, modv.y); + v.z = Mathf.PosMod(v.z, modv.z); + return v; + } + + public Vector3i Sign() + { + Vector3i v = this; + v.x = Mathf.Sign(v.x); + v.y = Mathf.Sign(v.y); + v.z = Mathf.Sign(v.z); + return v; + } + + // Constants + private static readonly Vector3i _zero = new Vector3i(0, 0, 0); + private static readonly Vector3i _one = new Vector3i(1, 1, 1); + + private static readonly Vector3i _up = new Vector3i(0, 1, 0); + private static readonly Vector3i _down = new Vector3i(0, -1, 0); + private static readonly Vector3i _right = new Vector3i(1, 0, 0); + private static readonly Vector3i _left = new Vector3i(-1, 0, 0); + private static readonly Vector3i _forward = new Vector3i(0, 0, -1); + private static readonly Vector3i _back = new Vector3i(0, 0, 1); + + public static Vector3i Zero { get { return _zero; } } + public static Vector3i One { get { return _one; } } + + public static Vector3i Up { get { return _up; } } + public static Vector3i Down { get { return _down; } } + public static Vector3i Right { get { return _right; } } + public static Vector3i Left { get { return _left; } } + public static Vector3i Forward { get { return _forward; } } + public static Vector3i Back { get { return _back; } } + + // Constructors + public Vector3i(int x, int y, int z) + { + this.x = x; + this.y = y; + this.z = z; + } + public Vector3i(Vector3i vi) + { + this.x = vi.x; + this.y = vi.y; + this.z = vi.z; + } + public Vector3i(Vector3 v) + { + this.x = Mathf.RoundToInt(v.x); + this.y = Mathf.RoundToInt(v.y); + this.z = Mathf.RoundToInt(v.z); + } + + public static Vector3i operator +(Vector3i left, Vector3i right) + { + left.x += right.x; + left.y += right.y; + left.z += right.z; + return left; + } + + public static Vector3i operator -(Vector3i left, Vector3i right) + { + left.x -= right.x; + left.y -= right.y; + left.z -= right.z; + return left; + } + + public static Vector3i operator -(Vector3i vec) + { + vec.x = -vec.x; + vec.y = -vec.y; + vec.z = -vec.z; + return vec; + } + + public static Vector3i operator *(Vector3i vec, int scale) + { + vec.x *= scale; + vec.y *= scale; + vec.z *= scale; + return vec; + } + + public static Vector3i operator *(int scale, Vector3i vec) + { + vec.x *= scale; + vec.y *= scale; + vec.z *= scale; + return vec; + } + + public static Vector3i operator *(Vector3i left, Vector3i right) + { + left.x *= right.x; + left.y *= right.y; + left.z *= right.z; + return left; + } + + public static Vector3i operator /(Vector3i vec, int divisor) + { + vec.x /= divisor; + vec.y /= divisor; + vec.z /= divisor; + return vec; + } + + public static Vector3i operator /(Vector3i vec, Vector3i divisorv) + { + vec.x /= divisorv.x; + vec.y /= divisorv.y; + vec.z /= divisorv.z; + return vec; + } + + public static Vector3i operator %(Vector3i vec, int divisor) + { + vec.x %= divisor; + vec.y %= divisor; + vec.z %= divisor; + return vec; + } + + public static Vector3i operator %(Vector3i vec, Vector3i divisorv) + { + vec.x %= divisorv.x; + vec.y %= divisorv.y; + vec.z %= divisorv.z; + return vec; + } + + public static Vector3i operator &(Vector3i vec, int and) + { + vec.x &= and; + vec.y &= and; + vec.z &= and; + return vec; + } + + public static Vector3i operator &(Vector3i vec, Vector3i andv) + { + vec.x &= andv.x; + vec.y &= andv.y; + vec.z &= andv.z; + return vec; + } + + public static bool operator ==(Vector3i left, Vector3i right) + { + return left.Equals(right); + } + + public static bool operator !=(Vector3i left, Vector3i right) + { + return !left.Equals(right); + } + + public static bool operator <(Vector3i left, Vector3i right) + { + if (left.x == right.x) + { + if (left.y == right.y) + return left.z < right.z; + else + return left.y < right.y; + } + + return left.x < right.x; + } + + public static bool operator >(Vector3i left, Vector3i right) + { + if (left.x == right.x) + { + if (left.y == right.y) + return left.z > right.z; + else + return left.y > right.y; + } + + return left.x > right.x; + } + + public static bool operator <=(Vector3i left, Vector3i right) + { + if (left.x == right.x) + { + if (left.y == right.y) + return left.z <= right.z; + else + return left.y < right.y; + } + + return left.x < right.x; + } + + public static bool operator >=(Vector3i left, Vector3i right) + { + if (left.x == right.x) + { + if (left.y == right.y) + return left.z >= right.z; + else + return left.y > right.y; + } + + return left.x > right.x; + } + + public static implicit operator Vector3(Vector3i value) + { + return new Vector3(value.x, value.y, value.z); + } + + public static explicit operator Vector3i(Vector3 value) + { + return new Vector3i(value); + } + + public override bool Equals(object obj) + { + if (obj is Vector3i) + { + return Equals((Vector3i)obj); + } + + return false; + } + + public bool Equals(Vector3i other) + { + return x == other.x && y == other.y && z == other.z; + } + + public override int GetHashCode() + { + return y.GetHashCode() ^ x.GetHashCode() ^ z.GetHashCode(); + } + + public override string ToString() + { + return String.Format("({0}, {1}, {2})", new object[] + { + this.x.ToString(), + this.y.ToString(), + this.z.ToString() + }); + } + + public string ToString(string format) + { + return String.Format("({0}, {1}, {2})", new object[] + { + this.x.ToString(format), + this.y.ToString(format), + this.z.ToString(format) + }); + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj index 5419cd06e6..ba0bbd7630 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj +++ b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj @@ -41,9 +41,11 @@ <Compile Include="Core\Attributes\SignalAttribute.cs" /> <Compile Include="Core\Attributes\ToolAttribute.cs" /> <Compile Include="Core\Basis.cs" /> + <Compile Include="Core\Callable.cs" /> <Compile Include="Core\Color.cs" /> <Compile Include="Core\Colors.cs" /> <Compile Include="Core\DebuggingUtils.cs" /> + <Compile Include="Core\DelegateUtils.cs" /> <Compile Include="Core\Dictionary.cs" /> <Compile Include="Core\Dispatcher.cs" /> <Compile Include="Core\DynamicObject.cs" /> @@ -65,13 +67,18 @@ <Compile Include="Core\Plane.cs" /> <Compile Include="Core\Quat.cs" /> <Compile Include="Core\Rect2.cs" /> + <Compile Include="Core\Rect2i.cs" /> <Compile Include="Core\RID.cs" /> + <Compile Include="Core\SignalInfo.cs" /> <Compile Include="Core\SignalAwaiter.cs" /> <Compile Include="Core\StringExtensions.cs" /> + <Compile Include="Core\StringName.cs" /> <Compile Include="Core\Transform.cs" /> <Compile Include="Core\Transform2D.cs" /> <Compile Include="Core\Vector2.cs" /> + <Compile Include="Core\Vector2i.cs" /> <Compile Include="Core\Vector3.cs" /> + <Compile Include="Core\Vector3i.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> </ItemGroup> <!-- diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp index 8c77220b85..120668d1ef 100644 --- a/modules/mono/glue/base_object_glue.cpp +++ b/modules/mono/glue/base_object_glue.cpp @@ -70,8 +70,8 @@ void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr) { if (data) { CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get(); if (script_binding.inited) { - Ref<MonoGCHandle> &gchandle = script_binding.gchandle; - if (gchandle.is_valid()) { + MonoGCHandleData &gchandle = script_binding.gchandle; + if (!gchandle.is_released()) { CSharpLanguage::release_script_gchandle(p_obj, gchandle); } } @@ -117,8 +117,8 @@ void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoolea if (data) { CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get(); if (script_binding.inited) { - Ref<MonoGCHandle> &gchandle = script_binding.gchandle; - if (gchandle.is_valid()) { + MonoGCHandleData &gchandle = script_binding.gchandle; + if (!gchandle.is_released()) { CSharpLanguage::release_script_gchandle(p_obj, gchandle); } } @@ -126,18 +126,25 @@ void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoolea } } -MethodBind *godot_icall_Object_ClassDB_get_method(MonoString *p_type, MonoString *p_method) { - StringName type(GDMonoMarshal::mono_string_to_godot(p_type)); +void godot_icall_Object_ConnectEventSignals(Object *p_ptr) { + CSharpInstance *csharp_instance = CAST_CSHARP_INSTANCE(p_ptr->get_script_instance()); + if (csharp_instance) { + csharp_instance->connect_event_signals(); + } +} + +MethodBind *godot_icall_Object_ClassDB_get_method(StringName *p_type, MonoString *p_method) { + StringName type = p_type ? *p_type : StringName(); StringName method(GDMonoMarshal::mono_string_to_godot(p_method)); return ClassDB::get_method(type, method); } -MonoObject *godot_icall_Object_weakref(Object *p_obj) { - if (!p_obj) +MonoObject *godot_icall_Object_weakref(Object *p_ptr) { + if (!p_ptr) return NULL; Ref<WeakRef> wref; - Reference *ref = Object::cast_to<Reference>(p_obj); + Reference *ref = Object::cast_to<Reference>(p_ptr); if (ref) { REF r = ref; @@ -148,15 +155,15 @@ MonoObject *godot_icall_Object_weakref(Object *p_obj) { wref->set_ref(r); } else { wref.instance(); - wref->set_obj(p_obj); + wref->set_obj(p_ptr); } return GDMonoUtils::unmanaged_get_managed(wref.ptr()); } -Error godot_icall_SignalAwaiter_connect(Object *p_source, MonoString *p_signal, Object *p_target, MonoObject *p_awaiter) { - String signal = GDMonoMarshal::mono_string_to_godot(p_signal); - return SignalAwaiterUtils::connect_signal_awaiter(p_source, signal, p_target, p_awaiter); +Error godot_icall_SignalAwaiter_connect(Object *p_source, StringName *p_signal, Object *p_target, MonoObject *p_awaiter) { + StringName signal = p_signal ? *p_signal : StringName(); + return gd_mono_connect_signal_awaiter(p_source, signal, p_target, p_awaiter); } MonoArray *godot_icall_DynamicGodotObject_SetMemberList(Object *p_ptr) { @@ -225,8 +232,8 @@ MonoString *godot_icall_Object_ToString(Object *p_ptr) { // Cannot happen in C#; would get an ObjectDisposedException instead. CRASH_COND(p_ptr == NULL); #endif - - String result = p_ptr->to_string(); + // Can't call 'Object::to_string()' here, as that can end up calling 'ToString' again resulting in an endless circular loop. + String result = "[" + p_ptr->get_class() + ":" + itos(p_ptr->get_instance_id()) + "]"; return GDMonoMarshal::mono_string_from_godot(result); } diff --git a/modules/mono/glue/base_object_glue.h b/modules/mono/glue/base_object_glue.h index 22532dcff9..67769f3061 100644 --- a/modules/mono/glue/base_object_glue.h +++ b/modules/mono/glue/base_object_glue.h @@ -44,11 +44,13 @@ void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr); void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoolean p_is_finalizer); -MethodBind *godot_icall_Object_ClassDB_get_method(MonoString *p_type, MonoString *p_method); +void godot_icall_Object_ConnectEventSignals(Object *p_ptr); -MonoObject *godot_icall_Object_weakref(Object *p_obj); +MethodBind *godot_icall_Object_ClassDB_get_method(StringName *p_type, MonoString *p_method); -Error godot_icall_SignalAwaiter_connect(Object *p_source, MonoString *p_signal, Object *p_target, MonoObject *p_awaiter); +MonoObject *godot_icall_Object_weakref(Object *p_ptr); + +Error godot_icall_SignalAwaiter_connect(Object *p_source, StringName *p_signal, Object *p_target, MonoObject *p_awaiter); // DynamicGodotObject diff --git a/modules/mono/glue/gd_glue.cpp b/modules/mono/glue/gd_glue.cpp index cdacd90538..1576d31a3b 100644 --- a/modules/mono/glue/gd_glue.cpp +++ b/modules/mono/glue/gd_glue.cpp @@ -241,8 +241,9 @@ MonoObject *godot_icall_GD_str2var(MonoString *p_str) { return GDMonoMarshal::variant_to_mono_object(ret); } -MonoBoolean godot_icall_GD_type_exists(MonoString *p_type) { - return ClassDB::class_exists(GDMonoMarshal::mono_string_to_godot(p_type)); +MonoBoolean godot_icall_GD_type_exists(StringName *p_type) { + StringName type = p_type ? *p_type : StringName(); + return ClassDB::class_exists(type); } void godot_icall_GD_pusherror(MonoString *p_str) { @@ -273,6 +274,10 @@ MonoString *godot_icall_GD_var2str(MonoObject *p_var) { return GDMonoMarshal::mono_string_from_godot(vars); } +uint32_t godot_icall_TypeToVariantType(MonoReflectionType *p_refl_type) { + return (uint32_t)GDMonoMarshal::managed_to_variant_type(ManagedType::from_reftype(p_refl_type)); +} + MonoObject *godot_icall_DefaultGodotTaskScheduler() { return GDMonoCache::cached_data.task_scheduler_handle->get_target(); } @@ -300,6 +305,7 @@ void godot_register_gd_icalls() { mono_add_internal_call("Godot.GD::godot_icall_GD_type_exists", (void *)godot_icall_GD_type_exists); mono_add_internal_call("Godot.GD::godot_icall_GD_var2bytes", (void *)godot_icall_GD_var2bytes); mono_add_internal_call("Godot.GD::godot_icall_GD_var2str", (void *)godot_icall_GD_var2str); + mono_add_internal_call("Godot.GD::godot_icall_TypeToVariantType", (void *)godot_icall_TypeToVariantType); // Dispatcher mono_add_internal_call("Godot.Dispatcher::godot_icall_DefaultGodotTaskScheduler", (void *)godot_icall_DefaultGodotTaskScheduler); diff --git a/modules/mono/glue/gd_glue.h b/modules/mono/glue/gd_glue.h index f00e2efc5d..3ad6058205 100644 --- a/modules/mono/glue/gd_glue.h +++ b/modules/mono/glue/gd_glue.h @@ -69,7 +69,7 @@ MonoString *godot_icall_GD_str(MonoArray *p_what); MonoObject *godot_icall_GD_str2var(MonoString *p_str); -MonoBoolean godot_icall_GD_type_exists(MonoString *p_type); +MonoBoolean godot_icall_GD_type_exists(StringName *p_type); MonoArray *godot_icall_GD_var2bytes(MonoObject *p_var, MonoBoolean p_full_objects); diff --git a/modules/mono/glue/glue_header.h b/modules/mono/glue/glue_header.h index 758b71f719..8130b0cc39 100644 --- a/modules/mono/glue/glue_header.h +++ b/modules/mono/glue/glue_header.h @@ -36,6 +36,7 @@ #include "nodepath_glue.h" #include "rid_glue.h" #include "string_glue.h" +#include "string_name_glue.h" /** * Registers internal calls that were not generated. This function is called @@ -44,6 +45,7 @@ void godot_register_glue_header_icalls() { godot_register_collections_icalls(); godot_register_gd_icalls(); + godot_register_string_name_icalls(); godot_register_nodepath_icalls(); godot_register_object_icalls(); godot_register_rid_icalls(); diff --git a/modules/mono/utils/thread_local.cpp b/modules/mono/glue/string_name_glue.cpp index 4f10e3fb85..81006e5849 100644 --- a/modules/mono/utils/thread_local.cpp +++ b/modules/mono/glue/string_name_glue.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* thread_local.cpp */ +/* string_name_glue.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,80 +28,34 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "thread_local.h" +#include "string_name_glue.h" -#ifdef WINDOWS_ENABLED -#include <windows.h> -#else -#include <pthread.h> -#endif +#ifdef MONO_GLUE_ENABLED -#include "core/os/memory.h" -#include "core/print_string.h" +#include "core/ustring.h" -struct ThreadLocalStorage::Impl { - -#ifdef WINDOWS_ENABLED - DWORD dwFlsIndex; -#else - pthread_key_t key; -#endif - - void *get_value() const { -#ifdef WINDOWS_ENABLED - return FlsGetValue(dwFlsIndex); -#else - return pthread_getspecific(key); -#endif - } - - void set_value(void *p_value) const { -#ifdef WINDOWS_ENABLED - FlsSetValue(dwFlsIndex, p_value); -#else - pthread_setspecific(key, p_value); -#endif - } - -#ifdef WINDOWS_ENABLED -#define _CALLBACK_FUNC_ __stdcall -#else -#define _CALLBACK_FUNC_ -#endif - - Impl(void(_CALLBACK_FUNC_ *p_destr_callback_func)(void *)) { -#ifdef WINDOWS_ENABLED - dwFlsIndex = FlsAlloc(p_destr_callback_func); - ERR_FAIL_COND(dwFlsIndex == FLS_OUT_OF_INDEXES); -#else - pthread_key_create(&key, p_destr_callback_func); -#endif - } - - ~Impl() { -#ifdef WINDOWS_ENABLED - FlsFree(dwFlsIndex); -#else - pthread_key_delete(key); -#endif - } -}; - -void *ThreadLocalStorage::get_value() const { - return pimpl->get_value(); +StringName *godot_icall_StringName_Ctor(MonoString *p_path) { + return memnew(StringName(GDMonoMarshal::mono_string_to_godot(p_path))); } -void ThreadLocalStorage::set_value(void *p_value) const { - pimpl->set_value(p_value); +void godot_icall_StringName_Dtor(StringName *p_ptr) { + ERR_FAIL_NULL(p_ptr); + memdelete(p_ptr); } -void ThreadLocalStorage::alloc(void(_CALLBACK_FUNC_ *p_destr_callback)(void *)) { - pimpl = memnew(ThreadLocalStorage::Impl(p_destr_callback)); +MonoString *godot_icall_StringName_operator_String(StringName *p_np) { + return GDMonoMarshal::mono_string_from_godot(p_np->operator String()); } -#undef _CALLBACK_FUNC_ +MonoBoolean godot_icall_StringName_is_empty(StringName *p_ptr) { + return (MonoBoolean)(p_ptr == StringName()); +} -void ThreadLocalStorage::free() { - memdelete(pimpl); - pimpl = NULL; +void godot_register_string_name_icalls() { + mono_add_internal_call("Godot.StringName::godot_icall_StringName_Ctor", (void *)godot_icall_StringName_Ctor); + mono_add_internal_call("Godot.StringName::godot_icall_StringName_Dtor", (void *)godot_icall_StringName_Dtor); + mono_add_internal_call("Godot.StringName::godot_icall_StringName_operator_String", (void *)godot_icall_StringName_operator_String); + mono_add_internal_call("Godot.StringName::godot_icall_StringName_is_empty", (void *)godot_icall_StringName_is_empty); } + +#endif // MONO_GLUE_ENABLED diff --git a/platform/android/java/lib/src/org/godotengine/godot/payments/GodotPaymentInterface.java b/modules/mono/glue/string_name_glue.h index 6ac7338b30..88354ddd84 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/GodotPaymentInterface.java +++ b/modules/mono/glue/string_name_glue.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* GodotPaymentInterface.java */ +/* string_name_glue.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -28,70 +28,27 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -package org.godotengine.godot.payments; +#ifndef STRING_NAME_GLUE_H +#define STRING_NAME_GLUE_H -public interface GodotPaymentInterface { - void purchase(String sku, String transactionId); +#ifdef MONO_GLUE_ENABLED - void consumeUnconsumedPurchases(); +#include "core/string_name.h" - String getSignature(); +#include "../mono_gd/gd_mono_marshal.h" - void callbackSuccess(String ticket, String signature, String sku); +StringName *godot_icall_StringName_Ctor(MonoString *p_path); - void callbackSuccessProductMassConsumed(String ticket, String signature, String sku); +void godot_icall_StringName_Dtor(StringName *p_ptr); - void callbackSuccessNoUnconsumedPurchases(); +MonoString *godot_icall_StringName_operator_String(StringName *p_np); - void callbackFailConsume(String message); +MonoBoolean godot_icall_StringName_is_empty(StringName *p_ptr); - void callbackFail(String message); +// Register internal calls - void callbackCancel(); +void godot_register_string_name_icalls(); - void callbackAlreadyOwned(String sku); +#endif // MONO_GLUE_ENABLED - int getPurchaseCallbackId(); - - void setPurchaseCallbackId(int purchaseCallbackId); - - String getPurchaseValidationUrlPrefix(); - - void setPurchaseValidationUrlPrefix(String url); - - String getAccessToken(); - - void setAccessToken(String accessToken); - - void setTransactionId(String transactionId); - - String getTransactionId(); - - // request purchased items are not consumed - void requestPurchased(); - - // callback for requestPurchased() - void callbackPurchased(String receipt, String signature, String sku); - - void callbackDisconnected(); - - void callbackConnected(); - - // true if connected, false otherwise - boolean isConnected(); - - // consume item automatically after purchase. default is true. - void setAutoConsume(boolean autoConsume); - - // consume a specific item - void consume(String sku); - - // query in app item detail info - void querySkuDetails(String[] list); - - void addSkuDetail(String itemJson); - - void completeSkuDetail(); - - void errorSkuDetail(String errorMessage); -} +#endif // STRING_NAME_GLUE_H diff --git a/modules/mono/managed_callable.cpp b/modules/mono/managed_callable.cpp new file mode 100644 index 0000000000..a9cf64d1cc --- /dev/null +++ b/modules/mono/managed_callable.cpp @@ -0,0 +1,145 @@ +/*************************************************************************/ +/* managed_callable.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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. */ +/*************************************************************************/ + +#include "managed_callable.h" + +#include "csharp_script.h" +#include "mono_gd/gd_mono_marshal.h" +#include "mono_gd/gd_mono_utils.h" + +#ifdef GD_MONO_HOT_RELOAD +SelfList<ManagedCallable>::List ManagedCallable::instances; +Map<ManagedCallable *, Array> ManagedCallable::instances_pending_reload; +Mutex ManagedCallable::instances_mutex; +#endif + +bool ManagedCallable::compare_equal(const CallableCustom *p_a, const CallableCustom *p_b) { + const ManagedCallable *a = static_cast<const ManagedCallable *>(p_a); + const ManagedCallable *b = static_cast<const ManagedCallable *>(p_b); + + MonoDelegate *delegate_a = (MonoDelegate *)a->delegate_handle.get_target(); + MonoDelegate *delegate_b = (MonoDelegate *)b->delegate_handle.get_target(); + + if (!delegate_a || !delegate_b) { + if (!delegate_a && !delegate_b) + return true; + return false; + } + + // Call Delegate's 'Equals' + return GDMonoUtils::mono_delegate_equal(delegate_a, delegate_b); +} + +bool ManagedCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) { + if (compare_equal(p_a, p_b)) + return false; + return p_a < p_b; +} + +uint32_t ManagedCallable::hash() const { + // hmm + uint32_t hash = delegate_invoke->get_name().hash(); + return hash_djb2_one_64(delegate_handle.handle, hash); +} + +String ManagedCallable::get_as_text() const { + return "Delegate::Invoke"; +} + +CallableCustom::CompareEqualFunc ManagedCallable::get_compare_equal_func() const { + return compare_equal_func_ptr; +} + +CallableCustom::CompareLessFunc ManagedCallable::get_compare_less_func() const { + return compare_less_func_ptr; +} + +ObjectID ManagedCallable::get_object() const { + return CSharpLanguage::get_singleton()->get_managed_callable_middleman()->get_instance_id(); +} + +void ManagedCallable::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const { + r_call_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; // Can't find anything better + r_return_value = Variant(); + +#ifdef GD_MONO_HOT_RELOAD + // Lost during hot-reload + ERR_FAIL_NULL(delegate_invoke); + ERR_FAIL_COND(delegate_handle.is_released()); +#endif + + ERR_FAIL_COND(delegate_invoke->get_parameters_count() < p_argcount); + + MonoObject *delegate = delegate_handle.get_target(); + + MonoException *exc = NULL; + MonoObject *ret = delegate_invoke->invoke(delegate, p_arguments, &exc); + + if (exc) { + GDMonoUtils::set_pending_exception(exc); + } else { + r_return_value = GDMonoMarshal::mono_object_to_variant(ret); + r_call_error.error = Callable::CallError::CALL_OK; + } +} + +void ManagedCallable::set_delegate(MonoDelegate *p_delegate) { + delegate_handle = MonoGCHandleData::new_strong_handle((MonoObject *)p_delegate); + MonoMethod *delegate_invoke_raw = mono_get_delegate_invoke(mono_object_get_class((MonoObject *)p_delegate)); + const StringName &delegate_invoke_name = CSharpLanguage::get_singleton()->get_string_names().delegate_invoke_method_name; + delegate_invoke = memnew(GDMonoMethod(delegate_invoke_name, delegate_invoke_raw)); // TODO: Use pooling for this GDMonoMethod instances +} + +ManagedCallable::ManagedCallable(MonoDelegate *p_delegate) { +#ifdef DEBUG_ENABLED + CRASH_COND(p_delegate == NULL); +#endif + + set_delegate(p_delegate); + +#ifdef GD_MONO_HOT_RELOAD + { + MutexLock lock(instances_mutex); + instances.add(&self_instance); + } +#endif +} + +ManagedCallable::~ManagedCallable() { +#ifdef GD_MONO_HOT_RELOAD + { + MutexLock lock(instances_mutex); + instances.remove(&self_instance); + instances_pending_reload.erase(this); + } +#endif + + delegate_handle.release(); +} diff --git a/modules/mono/managed_callable.h b/modules/mono/managed_callable.h new file mode 100644 index 0000000000..4f71e14a2f --- /dev/null +++ b/modules/mono/managed_callable.h @@ -0,0 +1,77 @@ +/*************************************************************************/ +/* managed_callable.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 MANAGED_CALLABLE_H +#define MANAGED_CALLABLE_H + +#include <mono/metadata/object.h> + +#include "core/callable.h" +#include "core/os/mutex.h" +#include "core/self_list.h" + +#include "mono_gc_handle.h" +#include "mono_gd/gd_mono_method.h" + +class ManagedCallable : public CallableCustom { + friend class CSharpLanguage; + MonoGCHandleData delegate_handle; + GDMonoMethod *delegate_invoke; + +#ifdef GD_MONO_HOT_RELOAD + SelfList<ManagedCallable> self_instance = this; + static SelfList<ManagedCallable>::List instances; + static Map<ManagedCallable *, Array> instances_pending_reload; + static Mutex instances_mutex; +#endif + +public: + uint32_t hash() const override; + String get_as_text() const override; + CompareEqualFunc get_compare_equal_func() const override; + CompareLessFunc get_compare_less_func() const override; + ObjectID get_object() const override; + void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override; + + _FORCE_INLINE_ MonoDelegate *get_delegate() { return (MonoDelegate *)delegate_handle.get_target(); } + + void set_delegate(MonoDelegate *p_delegate); + + static bool compare_equal(const CallableCustom *p_a, const CallableCustom *p_b); + static bool compare_less(const CallableCustom *p_a, const CallableCustom *p_b); + + static constexpr CompareEqualFunc compare_equal_func_ptr = &ManagedCallable::compare_equal; + static constexpr CompareEqualFunc compare_less_func_ptr = &ManagedCallable::compare_less; + + ManagedCallable(MonoDelegate *p_delegate); + ~ManagedCallable(); +}; + +#endif // MANAGED_CALLABLE_H diff --git a/modules/mono/mono_gc_handle.cpp b/modules/mono/mono_gc_handle.cpp index feeea848ee..4b6d7269e9 100644 --- a/modules/mono/mono_gc_handle.cpp +++ b/modules/mono/mono_gc_handle.cpp @@ -32,56 +32,35 @@ #include "mono_gd/gd_mono.h" -uint32_t MonoGCHandle::new_strong_handle(MonoObject *p_object) { - - return mono_gchandle_new(p_object, /* pinned: */ false); -} - -uint32_t MonoGCHandle::new_strong_handle_pinned(MonoObject *p_object) { - - return mono_gchandle_new(p_object, /* pinned: */ true); -} - -uint32_t MonoGCHandle::new_weak_handle(MonoObject *p_object) { - - return mono_gchandle_new_weakref(p_object, /* track_resurrection: */ false); -} - -void MonoGCHandle::free_handle(uint32_t p_gchandle) { +void MonoGCHandleData::release() { +#ifdef DEBUG_ENABLED + CRASH_COND(handle && GDMono::get_singleton() == NULL); +#endif - mono_gchandle_free(p_gchandle); + if (handle && GDMono::get_singleton()->is_runtime_initialized()) { + GDMonoUtils::free_gchandle(handle); + handle = 0; + } } -Ref<MonoGCHandle> MonoGCHandle::create_strong(MonoObject *p_object) { - - return memnew(MonoGCHandle(new_strong_handle(p_object), STRONG_HANDLE)); +MonoGCHandleData MonoGCHandleData::new_strong_handle(MonoObject *p_object) { + return MonoGCHandleData(GDMonoUtils::new_strong_gchandle(p_object), gdmono::GCHandleType::STRONG_HANDLE); } -Ref<MonoGCHandle> MonoGCHandle::create_weak(MonoObject *p_object) { - - return memnew(MonoGCHandle(new_weak_handle(p_object), WEAK_HANDLE)); +MonoGCHandleData MonoGCHandleData::new_strong_handle_pinned(MonoObject *p_object) { + return MonoGCHandleData(GDMonoUtils::new_strong_gchandle_pinned(p_object), gdmono::GCHandleType::STRONG_HANDLE); } -void MonoGCHandle::release() { - -#ifdef DEBUG_ENABLED - CRASH_COND(!released && GDMono::get_singleton() == NULL); -#endif - - if (!released && GDMono::get_singleton()->is_runtime_initialized()) { - free_handle(handle); - released = true; - } +MonoGCHandleData MonoGCHandleData::new_weak_handle(MonoObject *p_object) { + return MonoGCHandleData(GDMonoUtils::new_weak_gchandle(p_object), gdmono::GCHandleType::WEAK_HANDLE); } -MonoGCHandle::MonoGCHandle(uint32_t p_handle, HandleType p_handle_type) { +Ref<MonoGCHandleRef> MonoGCHandleRef::create_strong(MonoObject *p_object) { - released = false; - weak = p_handle_type == WEAK_HANDLE; - handle = p_handle; + return memnew(MonoGCHandleRef(MonoGCHandleData::new_strong_handle(p_object))); } -MonoGCHandle::~MonoGCHandle() { +Ref<MonoGCHandleRef> MonoGCHandleRef::create_weak(MonoObject *p_object) { - release(); + return memnew(MonoGCHandleRef(MonoGCHandleData::new_weak_handle(p_object))); } diff --git a/modules/mono/mono_gc_handle.h b/modules/mono/mono_gc_handle.h index 37fc7d8a17..705b2265ba 100644 --- a/modules/mono/mono_gc_handle.h +++ b/modules/mono/mono_gc_handle.h @@ -35,42 +35,79 @@ #include "core/reference.h" -class MonoGCHandle : public Reference { +namespace gdmono { - GDCLASS(MonoGCHandle, Reference); +enum class GCHandleType : char { + NIL, + STRONG_HANDLE, + WEAK_HANDLE +}; + +} - bool released; - bool weak; +// Manual release of the GC handle must be done when using this struct +struct MonoGCHandleData { uint32_t handle; + gdmono::GCHandleType type; -public: - enum HandleType { - STRONG_HANDLE, - WEAK_HANDLE - }; + _FORCE_INLINE_ bool is_released() const { return !handle; } + _FORCE_INLINE_ bool is_weak() const { return type == gdmono::GCHandleType::WEAK_HANDLE; } - static uint32_t new_strong_handle(MonoObject *p_object); - static uint32_t new_strong_handle_pinned(MonoObject *p_object); - static uint32_t new_weak_handle(MonoObject *p_object); - static void free_handle(uint32_t p_gchandle); + _FORCE_INLINE_ MonoObject *get_target() const { return handle ? mono_gchandle_get_target(handle) : NULL; } - static Ref<MonoGCHandle> create_strong(MonoObject *p_object); - static Ref<MonoGCHandle> create_weak(MonoObject *p_object); + void release(); - _FORCE_INLINE_ bool is_released() { return released; } - _FORCE_INLINE_ bool is_weak() { return weak; } + MonoGCHandleData &operator=(const MonoGCHandleData &p_other) { +#ifdef DEBUG_ENABLED + CRASH_COND(!is_released()); +#endif + handle = p_other.handle; + type = p_other.type; + return *this; + } - _FORCE_INLINE_ MonoObject *get_target() const { return released ? NULL : mono_gchandle_get_target(handle); } + MonoGCHandleData(const MonoGCHandleData &) = default; - _FORCE_INLINE_ void set_handle(uint32_t p_handle, HandleType p_handle_type) { - released = false; - weak = p_handle_type == WEAK_HANDLE; - handle = p_handle; + MonoGCHandleData() : + handle(0), + type(gdmono::GCHandleType::NIL) { } - void release(); - MonoGCHandle(uint32_t p_handle, HandleType p_handle_type); - ~MonoGCHandle(); + MonoGCHandleData(uint32_t p_handle, gdmono::GCHandleType p_type) : + handle(p_handle), + type(p_type) { + } + + static MonoGCHandleData new_strong_handle(MonoObject *p_object); + static MonoGCHandleData new_strong_handle_pinned(MonoObject *p_object); + static MonoGCHandleData new_weak_handle(MonoObject *p_object); +}; + +class MonoGCHandleRef : public Reference { + + GDCLASS(MonoGCHandleRef, Reference); + + MonoGCHandleData data; + +public: + static Ref<MonoGCHandleRef> create_strong(MonoObject *p_object); + static Ref<MonoGCHandleRef> create_weak(MonoObject *p_object); + + _FORCE_INLINE_ bool is_released() const { return data.is_released(); } + _FORCE_INLINE_ bool is_weak() const { return data.is_weak(); } + + _FORCE_INLINE_ MonoObject *get_target() const { return data.get_target(); } + + void release() { data.release(); } + + _FORCE_INLINE_ void set_handle(uint32_t p_handle, gdmono::GCHandleType p_handle_type) { + data = MonoGCHandleData(p_handle, p_handle_type); + } + + MonoGCHandleRef(const MonoGCHandleData &p_gc_handle_data) : + data(p_gc_handle_data) { + } + ~MonoGCHandleRef() { release(); } }; #endif // CSHARP_GC_HANDLE_H diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h index 306fa15f12..9528c64f8d 100644 --- a/modules/mono/mono_gd/gd_mono.h +++ b/modules/mono/mono_gd/gd_mono.h @@ -105,7 +105,7 @@ private: MonoDomain *root_domain; MonoDomain *scripts_domain; - HashMap<uint32_t, HashMap<String, GDMonoAssembly *> > assemblies; + HashMap<uint32_t, HashMap<String, GDMonoAssembly *>> assemblies; GDMonoAssembly *corlib_assembly; GDMonoAssembly *project_assembly; @@ -203,7 +203,7 @@ public: static GDMono *get_singleton() { return singleton; } - GD_NORETURN static void unhandled_exception_hook(MonoObject *p_exc, void *p_user_data); + [[noreturn]] static void unhandled_exception_hook(MonoObject *p_exc, void *p_user_data); UnhandledExceptionPolicy get_unhandled_exception_policy() const { return unhandled_exception_policy; } diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp index 6cf5377e2c..57b7653a00 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.cpp +++ b/modules/mono/mono_gd/gd_mono_assembly.cpp @@ -148,7 +148,7 @@ MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, void *user_d return res ? res->get_assembly() : NULL; } -static _THREAD_LOCAL_(MonoImage *) image_corlib_loading = NULL; +static thread_local MonoImage *image_corlib_loading = NULL; MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **, void *user_data, bool refonly) { diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp index 0ad90a510e..be0b846702 100644 --- a/modules/mono/mono_gd/gd_mono_cache.cpp +++ b/modules/mono/mono_gd/gd_mono_cache.cpp @@ -103,15 +103,19 @@ void CachedData::clear_godot_api_cache() { rawclass_Dictionary = NULL; class_Vector2 = NULL; + class_Vector2i = NULL; class_Rect2 = NULL; + class_Rect2i = NULL; class_Transform2D = NULL; class_Vector3 = NULL; + class_Vector3i = NULL; class_Basis = NULL; class_Quat = NULL; class_Transform = NULL; class_AABB = NULL; class_Color = NULL; class_Plane = NULL; + class_StringName = NULL; class_NodePath = NULL; class_RID = NULL; class_GodotObject = NULL; @@ -120,6 +124,8 @@ void CachedData::clear_godot_api_cache() { class_Control = NULL; class_Spatial = NULL; class_WeakRef = NULL; + class_Callable = NULL; + class_SignalInfo = NULL; class_Array = NULL; class_Dictionary = NULL; class_MarshalUtils = NULL; @@ -145,6 +151,7 @@ void CachedData::clear_godot_api_cache() { field_GodotMethodAttribute_methodName = NULL; field_GodotObject_ptr = NULL; + field_StringName_ptr = NULL; field_NodePath_ptr = NULL; field_Image_ptr = NULL; field_RID_ptr = NULL; @@ -153,9 +160,13 @@ void CachedData::clear_godot_api_cache() { methodthunk_Array_GetPtr.nullify(); methodthunk_Dictionary_GetPtr.nullify(); methodthunk_SignalAwaiter_SignalCallback.nullify(); - methodthunk_SignalAwaiter_FailureCallback.nullify(); methodthunk_GodotTaskScheduler_Activate.nullify(); + methodthunk_Delegate_Equals.nullify(); + + methodthunk_DelegateUtils_TrySerializeDelegate.nullify(); + methodthunk_DelegateUtils_TryDeserializeDelegate.nullify(); + // Start of MarshalUtils methods methodthunk_MarshalUtils_TypeIsGenericArray.nullify(); @@ -178,7 +189,7 @@ void CachedData::clear_godot_api_cache() { // End of MarshalUtils methods - task_scheduler_handle = Ref<MonoGCHandle>(); + task_scheduler_handle = Ref<MonoGCHandleRef>(); } #define GODOT_API_CLASS(m_class) (GDMono::get_singleton()->get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, #m_class)) @@ -211,6 +222,8 @@ void update_corlib_cache() { CACHE_METHOD_AND_CHECK(System_Diagnostics_StackTrace, ctor_Exception_bool, CACHED_CLASS(System_Diagnostics_StackTrace)->get_method_with_desc("System.Diagnostics.StackTrace:.ctor(System.Exception,bool)", true)); #endif + CACHE_METHOD_THUNK_AND_CHECK(Delegate, Equals, GDMono::get_singleton()->get_corlib_assembly()->get_class("System", "Delegate")->get_method_with_desc("System.Delegate:Equals(object)", 1)); + CACHE_CLASS_AND_CHECK(KeyNotFoundException, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections.Generic", "KeyNotFoundException")); cached_data.corlib_cache_updated = true; @@ -219,15 +232,19 @@ void update_corlib_cache() { void update_godot_api_cache() { CACHE_CLASS_AND_CHECK(Vector2, GODOT_API_CLASS(Vector2)); + CACHE_CLASS_AND_CHECK(Vector2i, GODOT_API_CLASS(Vector2i)); CACHE_CLASS_AND_CHECK(Rect2, GODOT_API_CLASS(Rect2)); + CACHE_CLASS_AND_CHECK(Rect2i, GODOT_API_CLASS(Rect2i)); CACHE_CLASS_AND_CHECK(Transform2D, GODOT_API_CLASS(Transform2D)); CACHE_CLASS_AND_CHECK(Vector3, GODOT_API_CLASS(Vector3)); + CACHE_CLASS_AND_CHECK(Vector3i, GODOT_API_CLASS(Vector3i)); CACHE_CLASS_AND_CHECK(Basis, GODOT_API_CLASS(Basis)); CACHE_CLASS_AND_CHECK(Quat, GODOT_API_CLASS(Quat)); CACHE_CLASS_AND_CHECK(Transform, GODOT_API_CLASS(Transform)); CACHE_CLASS_AND_CHECK(AABB, GODOT_API_CLASS(AABB)); CACHE_CLASS_AND_CHECK(Color, GODOT_API_CLASS(Color)); CACHE_CLASS_AND_CHECK(Plane, GODOT_API_CLASS(Plane)); + CACHE_CLASS_AND_CHECK(StringName, GODOT_API_CLASS(StringName)); CACHE_CLASS_AND_CHECK(NodePath, GODOT_API_CLASS(NodePath)); CACHE_CLASS_AND_CHECK(RID, GODOT_API_CLASS(RID)); CACHE_CLASS_AND_CHECK(GodotObject, GODOT_API_CLASS(Object)); @@ -236,6 +253,8 @@ void update_godot_api_cache() { CACHE_CLASS_AND_CHECK(Control, GODOT_API_CLASS(Control)); CACHE_CLASS_AND_CHECK(Spatial, GODOT_API_CLASS(Spatial)); CACHE_CLASS_AND_CHECK(WeakRef, GODOT_API_CLASS(WeakRef)); + CACHE_CLASS_AND_CHECK(Callable, GODOT_API_CLASS(Callable)); + CACHE_CLASS_AND_CHECK(SignalInfo, GODOT_API_CLASS(SignalInfo)); CACHE_CLASS_AND_CHECK(Array, GODOT_API_NS_CLASS(BINDINGS_NAMESPACE_COLLECTIONS, Array)); CACHE_CLASS_AND_CHECK(Dictionary, GODOT_API_NS_CLASS(BINDINGS_NAMESPACE_COLLECTIONS, Dictionary)); CACHE_CLASS_AND_CHECK(MarshalUtils, GODOT_API_CLASS(MarshalUtils)); @@ -261,6 +280,7 @@ void update_godot_api_cache() { CACHE_FIELD_AND_CHECK(GodotMethodAttribute, methodName, CACHED_CLASS(GodotMethodAttribute)->get_field("methodName")); CACHE_FIELD_AND_CHECK(GodotObject, ptr, CACHED_CLASS(GodotObject)->get_field(BINDINGS_PTR_FIELD)); + CACHE_FIELD_AND_CHECK(StringName, ptr, CACHED_CLASS(StringName)->get_field(BINDINGS_PTR_FIELD)); CACHE_FIELD_AND_CHECK(NodePath, ptr, CACHED_CLASS(NodePath)->get_field(BINDINGS_PTR_FIELD)); CACHE_FIELD_AND_CHECK(RID, ptr, CACHED_CLASS(RID)->get_field(BINDINGS_PTR_FIELD)); @@ -268,9 +288,11 @@ void update_godot_api_cache() { CACHE_METHOD_THUNK_AND_CHECK(Array, GetPtr, GODOT_API_NS_CLASS(BINDINGS_NAMESPACE_COLLECTIONS, Array)->get_method("GetPtr", 0)); CACHE_METHOD_THUNK_AND_CHECK(Dictionary, GetPtr, GODOT_API_NS_CLASS(BINDINGS_NAMESPACE_COLLECTIONS, Dictionary)->get_method("GetPtr", 0)); CACHE_METHOD_THUNK_AND_CHECK(SignalAwaiter, SignalCallback, GODOT_API_CLASS(SignalAwaiter)->get_method("SignalCallback", 1)); - CACHE_METHOD_THUNK_AND_CHECK(SignalAwaiter, FailureCallback, GODOT_API_CLASS(SignalAwaiter)->get_method("FailureCallback", 0)); CACHE_METHOD_THUNK_AND_CHECK(GodotTaskScheduler, Activate, GODOT_API_CLASS(GodotTaskScheduler)->get_method("Activate", 0)); + CACHE_METHOD_THUNK_AND_CHECK(DelegateUtils, TrySerializeDelegate, GODOT_API_CLASS(DelegateUtils)->get_method("TrySerializeDelegate", 2)); + CACHE_METHOD_THUNK_AND_CHECK(DelegateUtils, TryDeserializeDelegate, GODOT_API_CLASS(DelegateUtils)->get_method("TryDeserializeDelegate", 2)); + // Start of MarshalUtils methods CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericArray, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericArray", 1)); @@ -300,7 +322,7 @@ void update_godot_api_cache() { // TODO Move to CSharpLanguage::init() and do handle disposal MonoObject *task_scheduler = mono_object_new(mono_domain_get(), GODOT_API_CLASS(GodotTaskScheduler)->get_mono_ptr()); GDMonoUtils::runtime_object_init(task_scheduler, GODOT_API_CLASS(GodotTaskScheduler)); - cached_data.task_scheduler_handle = MonoGCHandle::create_strong(task_scheduler); + cached_data.task_scheduler_handle = MonoGCHandleRef::create_strong(task_scheduler); cached_data.godot_api_cache_updated = true; } diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h index 0458e91240..b2dacee67c 100644 --- a/modules/mono/mono_gd/gd_mono_cache.h +++ b/modules/mono/mono_gd/gd_mono_cache.h @@ -73,15 +73,19 @@ struct CachedData { // ----------------------------------------------- GDMonoClass *class_Vector2; + GDMonoClass *class_Vector2i; GDMonoClass *class_Rect2; + GDMonoClass *class_Rect2i; GDMonoClass *class_Transform2D; GDMonoClass *class_Vector3; + GDMonoClass *class_Vector3i; GDMonoClass *class_Basis; GDMonoClass *class_Quat; GDMonoClass *class_Transform; GDMonoClass *class_AABB; GDMonoClass *class_Color; GDMonoClass *class_Plane; + GDMonoClass *class_StringName; GDMonoClass *class_NodePath; GDMonoClass *class_RID; GDMonoClass *class_GodotObject; @@ -90,6 +94,8 @@ struct CachedData { GDMonoClass *class_Control; GDMonoClass *class_Spatial; GDMonoClass *class_WeakRef; + GDMonoClass *class_Callable; + GDMonoClass *class_SignalInfo; GDMonoClass *class_Array; GDMonoClass *class_Dictionary; GDMonoClass *class_MarshalUtils; @@ -115,6 +121,7 @@ struct CachedData { GDMonoField *field_GodotMethodAttribute_methodName; GDMonoField *field_GodotObject_ptr; + GDMonoField *field_StringName_ptr; GDMonoField *field_NodePath_ptr; GDMonoField *field_Image_ptr; GDMonoField *field_RID_ptr; @@ -123,9 +130,13 @@ struct CachedData { GDMonoMethodThunkR<Array *, MonoObject *> methodthunk_Array_GetPtr; GDMonoMethodThunkR<Dictionary *, MonoObject *> methodthunk_Dictionary_GetPtr; GDMonoMethodThunk<MonoObject *, MonoArray *> methodthunk_SignalAwaiter_SignalCallback; - GDMonoMethodThunk<MonoObject *> methodthunk_SignalAwaiter_FailureCallback; GDMonoMethodThunk<MonoObject *> methodthunk_GodotTaskScheduler_Activate; + GDMonoMethodThunkR<MonoBoolean, MonoObject *, MonoObject *> methodthunk_Delegate_Equals; + + GDMonoMethodThunkR<MonoBoolean, MonoDelegate *, MonoObject *> methodthunk_DelegateUtils_TrySerializeDelegate; + GDMonoMethodThunkR<MonoBoolean, MonoObject *, MonoDelegate **> methodthunk_DelegateUtils_TryDeserializeDelegate; + // Start of MarshalUtils methods GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericArray; @@ -148,7 +159,7 @@ struct CachedData { // End of MarshalUtils methods - Ref<MonoGCHandle> task_scheduler_handle; + Ref<MonoGCHandleRef> task_scheduler_handle; bool corlib_cache_updated; bool godot_api_cache_updated; @@ -193,10 +204,4 @@ _FORCE_INLINE_ bool tools_godot_api_check() { #define CACHED_METHOD_THUNK(m_class, m_method) (GDMonoCache::cached_data.methodthunk_##m_class##_##m_method) #define CACHED_PROPERTY(m_class, m_property) (GDMonoCache::cached_data.property_##m_class##_##m_property) -#ifdef REAL_T_IS_DOUBLE -#define REAL_T_MONOCLASS CACHED_CLASS_RAW(double) -#else -#define REAL_T_MONOCLASS CACHED_CLASS_RAW(float) -#endif - #endif // GD_MONO_CACHE_H diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp index 03b56c9949..11942c47d9 100644 --- a/modules/mono/mono_gd/gd_mono_field.cpp +++ b/modules/mono/mono_gd/gd_mono_field.cpp @@ -37,6 +37,10 @@ #include "gd_mono_marshal.h" #include "gd_mono_utils.h" +void GDMonoField::set_value(MonoObject *p_object, MonoObject *p_value) { + mono_field_set_value(p_object, mono_field, p_value); +} + void GDMonoField::set_value_raw(MonoObject *p_object, void *p_ptr) { mono_field_set_value(p_object, mono_field, &p_ptr); } @@ -128,11 +132,21 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ break; } + if (tclass == CACHED_CLASS(Vector2i)) { + SET_FROM_STRUCT(Vector2i); + break; + } + if (tclass == CACHED_CLASS(Rect2)) { SET_FROM_STRUCT(Rect2); break; } + if (tclass == CACHED_CLASS(Rect2i)) { + SET_FROM_STRUCT(Rect2i); + break; + } + if (tclass == CACHED_CLASS(Transform2D)) { SET_FROM_STRUCT(Transform2D); break; @@ -143,6 +157,11 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ break; } + if (tclass == CACHED_CLASS(Vector3i)) { + SET_FROM_STRUCT(Vector3i); + break; + } + if (tclass == CACHED_CLASS(Basis)) { SET_FROM_STRUCT(Basis); break; @@ -173,6 +192,18 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ break; } + if (tclass == CACHED_CLASS(Callable)) { + GDMonoMarshal::M_Callable val = GDMonoMarshal::callable_to_managed(p_value.operator Callable()); + mono_field_set_value(p_object, mono_field, &val); + break; + } + + if (tclass == CACHED_CLASS(SignalInfo)) { + GDMonoMarshal::M_SignalInfo val = GDMonoMarshal::signal_info_to_managed(p_value.operator Signal()); + mono_field_set_value(p_object, mono_field, &val); + break; + } + if (mono_class_is_enum(tclass->get_mono_ptr())) { MonoType *enum_basetype = mono_class_enum_basetype(tclass->get_mono_ptr()); switch (mono_type_get_type(enum_basetype)) { @@ -256,11 +287,21 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ break; } - if (array_type->eklass == REAL_T_MONOCLASS) { + if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) { + SET_FROM_ARRAY(PackedInt64Array); + break; + } + + if (array_type->eklass == CACHED_CLASS_RAW(float)) { SET_FROM_ARRAY(PackedFloat32Array); break; } + if (array_type->eklass == CACHED_CLASS_RAW(double)) { + SET_FROM_ARRAY(PackedFloat64Array); + break; + } + if (array_type->eklass == CACHED_CLASS_RAW(String)) { SET_FROM_ARRAY(PackedStringArray); break; @@ -294,6 +335,12 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ break; } + if (CACHED_CLASS(StringName) == type_class) { + MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator StringName()); + mono_field_set_value(p_object, mono_field, managed); + break; + } + if (CACHED_CLASS(NodePath) == type_class) { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator NodePath()); mono_field_set_value(p_object, mono_field, managed); @@ -386,12 +433,21 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ case Variant::VECTOR2: { SET_FROM_STRUCT(Vector2); } break; + case Variant::VECTOR2I: { + SET_FROM_STRUCT(Vector2i); + } break; case Variant::RECT2: { SET_FROM_STRUCT(Rect2); } break; + case Variant::RECT2I: { + SET_FROM_STRUCT(Rect2i); + } break; case Variant::VECTOR3: { SET_FROM_STRUCT(Vector3); } break; + case Variant::VECTOR3I: { + SET_FROM_STRUCT(Vector3i); + } break; case Variant::TRANSFORM2D: { SET_FROM_STRUCT(Transform2D); } break; @@ -413,6 +469,10 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ case Variant::COLOR: { SET_FROM_STRUCT(Color); } break; + case Variant::STRING_NAME: { + MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator StringName()); + mono_field_set_value(p_object, mono_field, managed); + } break; case Variant::NODE_PATH: { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator NodePath()); mono_field_set_value(p_object, mono_field, managed); @@ -424,8 +484,15 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ case Variant::OBJECT: { MonoObject *managed = GDMonoUtils::unmanaged_get_managed(p_value.operator Object *()); mono_field_set_value(p_object, mono_field, managed); - break; - } + } break; + case Variant::CALLABLE: { + GDMonoMarshal::M_Callable val = GDMonoMarshal::callable_to_managed(p_value.operator Callable()); + mono_field_set_value(p_object, mono_field, &val); + } break; + case Variant::SIGNAL: { + GDMonoMarshal::M_SignalInfo val = GDMonoMarshal::signal_info_to_managed(p_value.operator Signal()); + mono_field_set_value(p_object, mono_field, &val); + } break; case Variant::DICTIONARY: { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary)); mono_field_set_value(p_object, mono_field, managed); @@ -440,9 +507,15 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ case Variant::PACKED_INT32_ARRAY: { SET_FROM_ARRAY(PackedInt32Array); } break; + case Variant::PACKED_INT64_ARRAY: { + SET_FROM_ARRAY(PackedInt64Array); + } break; case Variant::PACKED_FLOAT32_ARRAY: { SET_FROM_ARRAY(PackedFloat32Array); } break; + case Variant::PACKED_FLOAT64_ARRAY: { + SET_FROM_ARRAY(PackedFloat64Array); + } break; case Variant::PACKED_STRING_ARRAY: { SET_FROM_ARRAY(PackedStringArray); } break; diff --git a/modules/mono/mono_gd/gd_mono_field.h b/modules/mono/mono_gd/gd_mono_field.h index 76ee0963c4..61f2c8f071 100644 --- a/modules/mono/mono_gd/gd_mono_field.h +++ b/modules/mono/mono_gd/gd_mono_field.h @@ -47,21 +47,22 @@ class GDMonoField : public IMonoClassMember { MonoCustomAttrInfo *attributes; public: - virtual GDMonoClass *get_enclosing_class() const GD_FINAL { return owner; } + virtual GDMonoClass *get_enclosing_class() const final { return owner; } - virtual MemberType get_member_type() const GD_FINAL { return MEMBER_TYPE_FIELD; } + virtual MemberType get_member_type() const final { return MEMBER_TYPE_FIELD; } - virtual StringName get_name() const GD_FINAL { return name; } + virtual StringName get_name() const final { return name; } - virtual bool is_static() GD_FINAL; - virtual Visibility get_visibility() GD_FINAL; + virtual bool is_static() final; + virtual Visibility get_visibility() final; - virtual bool has_attribute(GDMonoClass *p_attr_class) GD_FINAL; - virtual MonoObject *get_attribute(GDMonoClass *p_attr_class) GD_FINAL; + virtual bool has_attribute(GDMonoClass *p_attr_class) final; + virtual MonoObject *get_attribute(GDMonoClass *p_attr_class) final; void fetch_attributes(); _FORCE_INLINE_ ManagedType get_type() const { return type; } + void set_value(MonoObject *p_object, MonoObject *p_value); void set_value_raw(MonoObject *p_object, void *p_ptr); void set_value_from_variant(MonoObject *p_object, const Variant &p_value); diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp index b179b484f3..53e642f317 100644 --- a/modules/mono/mono_gd/gd_mono_internals.cpp +++ b/modules/mono/mono_gd/gd_mono_internals.cpp @@ -33,7 +33,6 @@ #include "../csharp_script.h" #include "../mono_gc_handle.h" #include "../utils/macros.h" -#include "../utils/thread_local.h" #include "gd_mono_class.h" #include "gd_mono_marshal.h" #include "gd_mono_utils.h" @@ -76,7 +75,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) { script_binding.inited = true; script_binding.type_name = NATIVE_GDMONOCLASS_NAME(klass); script_binding.wrapper_class = klass; - script_binding.gchandle = ref ? MonoGCHandle::create_weak(managed) : MonoGCHandle::create_strong(managed); + script_binding.gchandle = ref ? MonoGCHandleData::new_weak_handle(managed) : MonoGCHandleData::new_strong_handle(managed); script_binding.owner = unmanaged; if (ref) { @@ -102,15 +101,17 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) { return; } - Ref<MonoGCHandle> gchandle = ref ? MonoGCHandle::create_weak(managed) : MonoGCHandle::create_strong(managed); + MonoGCHandleData gchandle = ref ? MonoGCHandleData::new_weak_handle(managed) : MonoGCHandleData::new_strong_handle(managed); Ref<CSharpScript> script = CSharpScript::create_for_managed_type(klass, native); CRASH_COND(script.is_null()); - ScriptInstance *si = CSharpInstance::create_for_managed_type(unmanaged, script.ptr(), gchandle); + CSharpInstance *csharp_instance = CSharpInstance::create_for_managed_type(unmanaged, script.ptr(), gchandle); - unmanaged->set_script_and_instance(script, si); + unmanaged->set_script_and_instance(script, csharp_instance); + + csharp_instance->connect_event_signals(); } void unhandled_exception(MonoException *p_exc) { diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index 695be64d6e..0de5352752 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -30,13 +30,14 @@ #include "gd_mono_marshal.h" +#include "../signal_awaiter_utils.h" #include "gd_mono.h" #include "gd_mono_cache.h" #include "gd_mono_class.h" namespace GDMonoMarshal { -Variant::Type managed_to_variant_type(const ManagedType &p_type) { +Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_variant) { switch (p_type.type_encoding) { case MONO_TYPE_BOOLEAN: return Variant::BOOL; @@ -74,15 +75,24 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) { if (vtclass == CACHED_CLASS(Vector2)) return Variant::VECTOR2; + if (vtclass == CACHED_CLASS(Vector2i)) + return Variant::VECTOR2I; + if (vtclass == CACHED_CLASS(Rect2)) return Variant::RECT2; + if (vtclass == CACHED_CLASS(Rect2i)) + return Variant::RECT2I; + if (vtclass == CACHED_CLASS(Transform2D)) return Variant::TRANSFORM2D; if (vtclass == CACHED_CLASS(Vector3)) return Variant::VECTOR3; + if (vtclass == CACHED_CLASS(Vector3i)) + return Variant::VECTOR3I; + if (vtclass == CACHED_CLASS(Basis)) return Variant::BASIS; @@ -101,6 +111,12 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) { if (vtclass == CACHED_CLASS(Plane)) return Variant::PLANE; + if (vtclass == CACHED_CLASS(Callable)) + return Variant::CALLABLE; + + if (vtclass == CACHED_CLASS(SignalInfo)) + return Variant::SIGNAL; + if (mono_class_is_enum(vtclass->get_mono_ptr())) return Variant::INT; } break; @@ -118,9 +134,15 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) { if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) return Variant::PACKED_INT32_ARRAY; - if (array_type->eklass == REAL_T_MONOCLASS) + if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) + return Variant::PACKED_INT64_ARRAY; + + if (array_type->eklass == CACHED_CLASS_RAW(float)) return Variant::PACKED_FLOAT32_ARRAY; + if (array_type->eklass == CACHED_CLASS_RAW(double)) + return Variant::PACKED_FLOAT64_ARRAY; + if (array_type->eklass == CACHED_CLASS_RAW(String)) return Variant::PACKED_STRING_ARRAY; @@ -142,6 +164,10 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) { return Variant::OBJECT; } + if (CACHED_CLASS(StringName) == type_class) { + return Variant::STRING_NAME; + } + if (CACHED_CLASS(NodePath) == type_class) { return Variant::NODE_PATH; } @@ -179,6 +205,12 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) { } } break; + case MONO_TYPE_OBJECT: { + if (r_nil_is_variant) + *r_nil_is_variant = true; + return Variant::NIL; + } break; + case MONO_TYPE_GENERICINST: { MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type()); @@ -211,6 +243,9 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) { } break; } + if (r_nil_is_variant) + *r_nil_is_variant = false; + // Unknown return Variant::NIL; } @@ -387,11 +422,21 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector2), &from); } + if (vtclass == CACHED_CLASS(Vector2i)) { + GDMonoMarshal::M_Vector2i from = MARSHALLED_OUT(Vector2i, p_var->operator ::Vector2i()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector2i), &from); + } + if (vtclass == CACHED_CLASS(Rect2)) { GDMonoMarshal::M_Rect2 from = MARSHALLED_OUT(Rect2, p_var->operator ::Rect2()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Rect2), &from); } + if (vtclass == CACHED_CLASS(Rect2i)) { + GDMonoMarshal::M_Rect2i from = MARSHALLED_OUT(Rect2i, p_var->operator ::Rect2i()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Rect2i), &from); + } + if (vtclass == CACHED_CLASS(Transform2D)) { GDMonoMarshal::M_Transform2D from = MARSHALLED_OUT(Transform2D, p_var->operator ::Transform2D()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform2D), &from); @@ -402,6 +447,11 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector3), &from); } + if (vtclass == CACHED_CLASS(Vector3i)) { + GDMonoMarshal::M_Vector3i from = MARSHALLED_OUT(Vector3i, p_var->operator ::Vector3i()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector3i), &from); + } + if (vtclass == CACHED_CLASS(Basis)) { GDMonoMarshal::M_Basis from = MARSHALLED_OUT(Basis, p_var->operator ::Basis()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Basis), &from); @@ -432,6 +482,16 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Plane), &from); } + if (vtclass == CACHED_CLASS(Callable)) { + GDMonoMarshal::M_Callable from = GDMonoMarshal::callable_to_managed(p_var->operator Callable()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Callable), &from); + } + + if (vtclass == CACHED_CLASS(SignalInfo)) { + GDMonoMarshal::M_SignalInfo from = GDMonoMarshal::signal_info_to_managed(p_var->operator Signal()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(SignalInfo), &from); + } + if (mono_class_is_enum(vtclass->get_mono_ptr())) { MonoType *enum_basetype = mono_class_enum_basetype(vtclass->get_mono_ptr()); MonoClass *enum_baseclass = mono_class_from_mono_type(enum_basetype); @@ -496,9 +556,15 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) return (MonoObject *)PackedInt32Array_to_mono_array(p_var->operator PackedInt32Array()); - if (array_type->eklass == REAL_T_MONOCLASS) + if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) + return (MonoObject *)PackedInt64Array_to_mono_array(p_var->operator PackedInt64Array()); + + if (array_type->eklass == CACHED_CLASS_RAW(float)) return (MonoObject *)PackedFloat32Array_to_mono_array(p_var->operator PackedFloat32Array()); + if (array_type->eklass == CACHED_CLASS_RAW(double)) + return (MonoObject *)PackedFloat64Array_to_mono_array(p_var->operator PackedFloat64Array()); + if (array_type->eklass == CACHED_CLASS_RAW(String)) return (MonoObject *)PackedStringArray_to_mono_array(p_var->operator PackedStringArray()); @@ -522,6 +588,10 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty return GDMonoUtils::unmanaged_get_managed(p_var->operator Object *()); } + if (CACHED_CLASS(StringName) == type_class) { + return GDMonoUtils::create_managed_from(p_var->operator StringName()); + } + if (CACHED_CLASS(NodePath) == type_class) { return GDMonoUtils::create_managed_from(p_var->operator NodePath()); } @@ -592,14 +662,26 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty GDMonoMarshal::M_Vector2 from = MARSHALLED_OUT(Vector2, p_var->operator ::Vector2()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector2), &from); } + case Variant::VECTOR2I: { + GDMonoMarshal::M_Vector2i from = MARSHALLED_OUT(Vector2i, p_var->operator ::Vector2i()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector2i), &from); + } case Variant::RECT2: { GDMonoMarshal::M_Rect2 from = MARSHALLED_OUT(Rect2, p_var->operator ::Rect2()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Rect2), &from); } + case Variant::RECT2I: { + GDMonoMarshal::M_Rect2i from = MARSHALLED_OUT(Rect2i, p_var->operator ::Rect2i()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Rect2i), &from); + } case Variant::VECTOR3: { GDMonoMarshal::M_Vector3 from = MARSHALLED_OUT(Vector3, p_var->operator ::Vector3()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector3), &from); } + case Variant::VECTOR3I: { + GDMonoMarshal::M_Vector3i from = MARSHALLED_OUT(Vector3i, p_var->operator ::Vector3i()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector3i), &from); + } case Variant::TRANSFORM2D: { GDMonoMarshal::M_Transform2D from = MARSHALLED_OUT(Transform2D, p_var->operator ::Transform2D()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform2D), &from); @@ -628,12 +710,22 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty GDMonoMarshal::M_Color from = MARSHALLED_OUT(Color, p_var->operator ::Color()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Color), &from); } + case Variant::STRING_NAME: + return GDMonoUtils::create_managed_from(p_var->operator StringName()); case Variant::NODE_PATH: return GDMonoUtils::create_managed_from(p_var->operator NodePath()); case Variant::_RID: return GDMonoUtils::create_managed_from(p_var->operator RID()); case Variant::OBJECT: return GDMonoUtils::unmanaged_get_managed(p_var->operator Object *()); + case Variant::CALLABLE: { + GDMonoMarshal::M_Callable from = GDMonoMarshal::callable_to_managed(p_var->operator Callable()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Callable), &from); + } + case Variant::SIGNAL: { + GDMonoMarshal::M_SignalInfo from = GDMonoMarshal::signal_info_to_managed(p_var->operator Signal()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(SignalInfo), &from); + } case Variant::DICTIONARY: return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary)); case Variant::ARRAY: @@ -642,8 +734,12 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty return (MonoObject *)PackedByteArray_to_mono_array(p_var->operator PackedByteArray()); case Variant::PACKED_INT32_ARRAY: return (MonoObject *)PackedInt32Array_to_mono_array(p_var->operator PackedInt32Array()); + case Variant::PACKED_INT64_ARRAY: + return (MonoObject *)PackedInt64Array_to_mono_array(p_var->operator PackedInt64Array()); case Variant::PACKED_FLOAT32_ARRAY: return (MonoObject *)PackedFloat32Array_to_mono_array(p_var->operator PackedFloat32Array()); + case Variant::PACKED_FLOAT64_ARRAY: + return (MonoObject *)PackedFloat64Array_to_mono_array(p_var->operator PackedFloat64Array()); case Variant::PACKED_STRING_ARRAY: return (MonoObject *)PackedStringArray_to_mono_array(p_var->operator PackedStringArray()); case Variant::PACKED_VECTOR2_ARRAY: @@ -744,34 +840,49 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type GDMonoClass *vtclass = p_type.type_class; if (vtclass == CACHED_CLASS(Vector2)) - return MARSHALLED_IN(Vector2, (GDMonoMarshal::M_Vector2 *)mono_object_unbox(p_obj)); + return MARSHALLED_IN(Vector2, unbox_addr<GDMonoMarshal::M_Vector2>(p_obj)); + + if (vtclass == CACHED_CLASS(Vector2i)) + return MARSHALLED_IN(Vector2i, unbox_addr<GDMonoMarshal::M_Vector2i>(p_obj)); if (vtclass == CACHED_CLASS(Rect2)) - return MARSHALLED_IN(Rect2, (GDMonoMarshal::M_Rect2 *)mono_object_unbox(p_obj)); + return MARSHALLED_IN(Rect2, unbox_addr<GDMonoMarshal::M_Rect2>(p_obj)); + + if (vtclass == CACHED_CLASS(Rect2i)) + return MARSHALLED_IN(Rect2i, unbox_addr<GDMonoMarshal::M_Rect2i>(p_obj)); if (vtclass == CACHED_CLASS(Transform2D)) - return MARSHALLED_IN(Transform2D, (GDMonoMarshal::M_Transform2D *)mono_object_unbox(p_obj)); + return MARSHALLED_IN(Transform2D, unbox_addr<GDMonoMarshal::M_Transform2D>(p_obj)); if (vtclass == CACHED_CLASS(Vector3)) - return MARSHALLED_IN(Vector3, (GDMonoMarshal::M_Vector3 *)mono_object_unbox(p_obj)); + return MARSHALLED_IN(Vector3, unbox_addr<GDMonoMarshal::M_Vector3>(p_obj)); + + if (vtclass == CACHED_CLASS(Vector3i)) + return MARSHALLED_IN(Vector3i, unbox_addr<GDMonoMarshal::M_Vector3i>(p_obj)); if (vtclass == CACHED_CLASS(Basis)) - return MARSHALLED_IN(Basis, (GDMonoMarshal::M_Basis *)mono_object_unbox(p_obj)); + return MARSHALLED_IN(Basis, unbox_addr<GDMonoMarshal::M_Basis>(p_obj)); if (vtclass == CACHED_CLASS(Quat)) - return MARSHALLED_IN(Quat, (GDMonoMarshal::M_Quat *)mono_object_unbox(p_obj)); + return MARSHALLED_IN(Quat, unbox_addr<GDMonoMarshal::M_Quat>(p_obj)); if (vtclass == CACHED_CLASS(Transform)) - return MARSHALLED_IN(Transform, (GDMonoMarshal::M_Transform *)mono_object_unbox(p_obj)); + return MARSHALLED_IN(Transform, unbox_addr<GDMonoMarshal::M_Transform>(p_obj)); if (vtclass == CACHED_CLASS(AABB)) - return MARSHALLED_IN(AABB, (GDMonoMarshal::M_AABB *)mono_object_unbox(p_obj)); + return MARSHALLED_IN(AABB, unbox_addr<GDMonoMarshal::M_AABB>(p_obj)); if (vtclass == CACHED_CLASS(Color)) - return MARSHALLED_IN(Color, (GDMonoMarshal::M_Color *)mono_object_unbox(p_obj)); + return MARSHALLED_IN(Color, unbox_addr<GDMonoMarshal::M_Color>(p_obj)); if (vtclass == CACHED_CLASS(Plane)) - return MARSHALLED_IN(Plane, (GDMonoMarshal::M_Plane *)mono_object_unbox(p_obj)); + return MARSHALLED_IN(Plane, unbox_addr<GDMonoMarshal::M_Plane>(p_obj)); + + if (vtclass == CACHED_CLASS(Callable)) + return managed_to_callable(unbox<GDMonoMarshal::M_Callable>(p_obj)); + + if (vtclass == CACHED_CLASS(SignalInfo)) + return managed_to_signal_info(unbox<GDMonoMarshal::M_SignalInfo>(p_obj)); if (mono_class_is_enum(vtclass->get_mono_ptr())) return unbox<int32_t>(p_obj); @@ -790,9 +901,15 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) return mono_array_to_PackedInt32Array((MonoArray *)p_obj); - if (array_type->eklass == REAL_T_MONOCLASS) + if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) + return mono_array_to_PackedInt64Array((MonoArray *)p_obj); + + if (array_type->eklass == CACHED_CLASS_RAW(float)) return mono_array_to_PackedFloat32Array((MonoArray *)p_obj); + if (array_type->eklass == CACHED_CLASS_RAW(double)) + return mono_array_to_PackedFloat64Array((MonoArray *)p_obj); + if (array_type->eklass == CACHED_CLASS_RAW(String)) return mono_array_to_PackedStringArray((MonoArray *)p_obj); @@ -825,6 +942,11 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type return Variant(); } + if (CACHED_CLASS(StringName) == type_class) { + StringName *ptr = unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_obj)); + return ptr ? Variant(*ptr) : Variant(); + } + if (CACHED_CLASS(NodePath) == type_class) { NodePath *ptr = unbox<NodePath *>(CACHED_FIELD(NodePath, ptr)->get_value(p_obj)); return ptr ? Variant(*ptr) : Variant(); @@ -960,9 +1082,10 @@ String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc) { } MonoArray *Array_to_mono_array(const Array &p_array) { - MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), p_array.size()); + int length = p_array.size(); + MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), length); - for (int i = 0; i < p_array.size(); i++) { + for (int i = 0; i < length; i++) { MonoObject *boxed = variant_to_mono_object(p_array[i]); mono_array_setref(ret, i, boxed); } @@ -985,16 +1108,14 @@ Array mono_array_to_Array(MonoArray *p_array) { return ret; } -// TODO: Use memcpy where possible - MonoArray *PackedInt32Array_to_mono_array(const PackedInt32Array &p_array) { - const int *r = p_array.ptr(); + const int32_t *src = p_array.ptr(); + int length = p_array.size(); - MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(int32_t), p_array.size()); + MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(int32_t), length); - for (int i = 0; i < p_array.size(); i++) { - mono_array_set(ret, int32_t, i, r[i]); - } + int32_t *dst = (int32_t *)mono_array_addr(ret, int32_t, 0); + memcpy(dst, src, length); return ret; } @@ -1005,23 +1126,48 @@ PackedInt32Array mono_array_to_PackedInt32Array(MonoArray *p_array) { return ret; int length = mono_array_length(p_array); ret.resize(length); - int *w = ret.ptrw(); + int32_t *dst = ret.ptrw(); - for (int i = 0; i < length; i++) { - w[i] = mono_array_get(p_array, int32_t, i); - } + const int32_t *src = (const int32_t *)mono_array_addr(p_array, int32_t, 0); + memcpy(dst, src, length); + + return ret; +} + +MonoArray *PackedInt64Array_to_mono_array(const PackedInt64Array &p_array) { + const int64_t *src = p_array.ptr(); + int length = p_array.size(); + + MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(int64_t), length); + + int64_t *dst = (int64_t *)mono_array_addr(ret, int64_t, 0); + memcpy(dst, src, length); + + return ret; +} + +PackedInt64Array mono_array_to_PackedInt64Array(MonoArray *p_array) { + PackedInt64Array ret; + if (!p_array) + return ret; + int length = mono_array_length(p_array); + ret.resize(length); + int64_t *dst = ret.ptrw(); + + const int64_t *src = (const int64_t *)mono_array_addr(p_array, int64_t, 0); + memcpy(dst, src, length); return ret; } MonoArray *PackedByteArray_to_mono_array(const PackedByteArray &p_array) { - const uint8_t *r = p_array.ptr(); + const uint8_t *src = p_array.ptr(); + int length = p_array.size(); - MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(uint8_t), p_array.size()); + MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(uint8_t), length); - for (int i = 0; i < p_array.size(); i++) { - mono_array_set(ret, uint8_t, i, r[i]); - } + uint8_t *dst = (uint8_t *)mono_array_addr(ret, uint8_t, 0); + memcpy(dst, src, length); return ret; } @@ -1032,23 +1178,22 @@ PackedByteArray mono_array_to_PackedByteArray(MonoArray *p_array) { return ret; int length = mono_array_length(p_array); ret.resize(length); - uint8_t *w = ret.ptrw(); + uint8_t *dst = ret.ptrw(); - for (int i = 0; i < length; i++) { - w[i] = mono_array_get(p_array, uint8_t, i); - } + const uint8_t *src = (const uint8_t *)mono_array_addr(p_array, uint8_t, 0); + memcpy(dst, src, length); return ret; } MonoArray *PackedFloat32Array_to_mono_array(const PackedFloat32Array &p_array) { - const real_t *r = p_array.ptr(); + const float *src = p_array.ptr(); + int length = p_array.size(); - MonoArray *ret = mono_array_new(mono_domain_get(), REAL_T_MONOCLASS, p_array.size()); + MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(float), length); - for (int i = 0; i < p_array.size(); i++) { - mono_array_set(ret, real_t, i, r[i]); - } + float *dst = (float *)mono_array_addr(ret, float, 0); + memcpy(dst, src, length); return ret; } @@ -1059,21 +1204,47 @@ PackedFloat32Array mono_array_to_PackedFloat32Array(MonoArray *p_array) { return ret; int length = mono_array_length(p_array); ret.resize(length); - real_t *w = ret.ptrw(); + float *dst = ret.ptrw(); - for (int i = 0; i < length; i++) { - w[i] = mono_array_get(p_array, real_t, i); - } + const float *src = (const float *)mono_array_addr(p_array, float, 0); + memcpy(dst, src, length); + + return ret; +} + +MonoArray *PackedFloat64Array_to_mono_array(const PackedFloat64Array &p_array) { + const double *src = p_array.ptr(); + int length = p_array.size(); + + MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(double), length); + + double *dst = (double *)mono_array_addr(ret, double, 0); + memcpy(dst, src, length); + + return ret; +} + +PackedFloat64Array mono_array_to_PackedFloat64Array(MonoArray *p_array) { + PackedFloat64Array ret; + if (!p_array) + return ret; + int length = mono_array_length(p_array); + ret.resize(length); + double *dst = ret.ptrw(); + + const double *src = (const double *)mono_array_addr(p_array, double, 0); + memcpy(dst, src, length); return ret; } MonoArray *PackedStringArray_to_mono_array(const PackedStringArray &p_array) { const String *r = p_array.ptr(); + int length = p_array.size(); - MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(String), p_array.size()); + MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(String), length); - for (int i = 0; i < p_array.size(); i++) { + for (int i = 0; i < length; i++) { MonoString *boxed = mono_string_from_godot(r[i]); mono_array_setref(ret, i, boxed); } @@ -1098,13 +1269,19 @@ PackedStringArray mono_array_to_PackedStringArray(MonoArray *p_array) { } MonoArray *PackedColorArray_to_mono_array(const PackedColorArray &p_array) { - const Color *r = p_array.ptr(); + const Color *src = p_array.ptr(); + int length = p_array.size(); - MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Color), p_array.size()); + MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Color), length); - for (int i = 0; i < p_array.size(); i++) { - M_Color *raw = (M_Color *)mono_array_addr_with_size(ret, sizeof(M_Color), i); - *raw = MARSHALLED_OUT(Color, r[i]); + if constexpr (InteropLayout::MATCHES_Color) { + Color *dst = (Color *)mono_array_addr(ret, Color, 0); + memcpy(dst, src, length); + } else { + for (int i = 0; i < length; i++) { + M_Color *raw = (M_Color *)mono_array_addr_with_size(ret, sizeof(M_Color), i); + *raw = MARSHALLED_OUT(Color, src[i]); + } } return ret; @@ -1116,23 +1293,34 @@ PackedColorArray mono_array_to_PackedColorArray(MonoArray *p_array) { return ret; int length = mono_array_length(p_array); ret.resize(length); - Color *w = ret.ptrw(); + Color *dst = ret.ptrw(); - for (int i = 0; i < length; i++) { - w[i] = MARSHALLED_IN(Color, (M_Color *)mono_array_addr_with_size(p_array, sizeof(M_Color), i)); + if constexpr (InteropLayout::MATCHES_Color) { + const Color *src = (const Color *)mono_array_addr(p_array, Color, 0); + memcpy(dst, src, length); + } else { + for (int i = 0; i < length; i++) { + dst[i] = MARSHALLED_IN(Color, (M_Color *)mono_array_addr_with_size(p_array, sizeof(M_Color), i)); + } } return ret; } MonoArray *PackedVector2Array_to_mono_array(const PackedVector2Array &p_array) { - const Vector2 *r = p_array.ptr(); + const Vector2 *src = p_array.ptr(); + int length = p_array.size(); - MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector2), p_array.size()); + MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector2), length); - for (int i = 0; i < p_array.size(); i++) { - M_Vector2 *raw = (M_Vector2 *)mono_array_addr_with_size(ret, sizeof(M_Vector2), i); - *raw = MARSHALLED_OUT(Vector2, r[i]); + if constexpr (InteropLayout::MATCHES_Vector2) { + Vector2 *dst = (Vector2 *)mono_array_addr(ret, Vector2, 0); + memcpy(dst, src, length); + } else { + for (int i = 0; i < length; i++) { + M_Vector2 *raw = (M_Vector2 *)mono_array_addr_with_size(ret, sizeof(M_Vector2), i); + *raw = MARSHALLED_OUT(Vector2, src[i]); + } } return ret; @@ -1144,23 +1332,34 @@ PackedVector2Array mono_array_to_PackedVector2Array(MonoArray *p_array) { return ret; int length = mono_array_length(p_array); ret.resize(length); - Vector2 *w = ret.ptrw(); + Vector2 *dst = ret.ptrw(); - for (int i = 0; i < length; i++) { - w[i] = MARSHALLED_IN(Vector2, (M_Vector2 *)mono_array_addr_with_size(p_array, sizeof(M_Vector2), i)); + if constexpr (InteropLayout::MATCHES_Vector2) { + const Vector2 *src = (const Vector2 *)mono_array_addr(p_array, Vector2, 0); + memcpy(dst, src, length); + } else { + for (int i = 0; i < length; i++) { + dst[i] = MARSHALLED_IN(Vector2, (M_Vector2 *)mono_array_addr_with_size(p_array, sizeof(M_Vector2), i)); + } } return ret; } MonoArray *PackedVector3Array_to_mono_array(const PackedVector3Array &p_array) { - const Vector3 *r = p_array.ptr(); + const Vector3 *src = p_array.ptr(); + int length = p_array.size(); - MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector3), p_array.size()); + MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector3), length); - for (int i = 0; i < p_array.size(); i++) { - M_Vector3 *raw = (M_Vector3 *)mono_array_addr_with_size(ret, sizeof(M_Vector3), i); - *raw = MARSHALLED_OUT(Vector3, r[i]); + if constexpr (InteropLayout::MATCHES_Vector3) { + Vector3 *dst = (Vector3 *)mono_array_addr(ret, Vector3, 0); + memcpy(dst, src, length); + } else { + for (int i = 0; i < length; i++) { + M_Vector3 *raw = (M_Vector3 *)mono_array_addr_with_size(ret, sizeof(M_Vector3), i); + *raw = MARSHALLED_OUT(Vector3, src[i]); + } } return ret; @@ -1172,13 +1371,85 @@ PackedVector3Array mono_array_to_PackedVector3Array(MonoArray *p_array) { return ret; int length = mono_array_length(p_array); ret.resize(length); - Vector3 *w = ret.ptrw(); + Vector3 *dst = ret.ptrw(); - for (int i = 0; i < length; i++) { - w[i] = MARSHALLED_IN(Vector3, (M_Vector3 *)mono_array_addr_with_size(p_array, sizeof(M_Vector3), i)); + if constexpr (InteropLayout::MATCHES_Vector3) { + const Vector3 *src = (const Vector3 *)mono_array_addr(p_array, Vector3, 0); + memcpy(dst, src, length); + } else { + for (int i = 0; i < length; i++) { + dst[i] = MARSHALLED_IN(Vector3, (M_Vector3 *)mono_array_addr_with_size(p_array, sizeof(M_Vector3), i)); + } } return ret; } +Callable managed_to_callable(const M_Callable &p_managed_callable) { + if (p_managed_callable.delegate) { + // TODO: Use pooling for ManagedCallable instances. + CallableCustom *managed_callable = memnew(ManagedCallable(p_managed_callable.delegate)); + return Callable(managed_callable); + } else { + Object *target = p_managed_callable.target ? + unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_callable.target)) : + NULL; + StringName *method_ptr = unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_callable.method_string_name)); + StringName method = method_ptr ? *method_ptr : StringName(); + return Callable(target, method); + } +} + +M_Callable callable_to_managed(const Callable &p_callable) { + if (p_callable.is_custom()) { + CallableCustom *custom = p_callable.get_custom(); + CallableCustom::CompareEqualFunc compare_equal_func = custom->get_compare_equal_func(); + + if (compare_equal_func == ManagedCallable::compare_equal_func_ptr) { + ManagedCallable *managed_callable = static_cast<ManagedCallable *>(custom); + return { + NULL, NULL, + managed_callable->get_delegate() + }; + } else if (compare_equal_func == SignalAwaiterCallable::compare_equal_func_ptr) { + SignalAwaiterCallable *signal_awaiter_callable = static_cast<SignalAwaiterCallable *>(custom); + return { + GDMonoUtils::unmanaged_get_managed(ObjectDB::get_instance(signal_awaiter_callable->get_object())), + GDMonoUtils::create_managed_from(signal_awaiter_callable->get_signal()), + NULL + }; + } else if (compare_equal_func == EventSignalCallable::compare_equal_func_ptr) { + EventSignalCallable *event_signal_callable = static_cast<EventSignalCallable *>(custom); + return { + GDMonoUtils::unmanaged_get_managed(ObjectDB::get_instance(event_signal_callable->get_object())), + GDMonoUtils::create_managed_from(event_signal_callable->get_signal()), + NULL + }; + } + + // Some other CallableCustom. We only support ManagedCallable. + return { NULL, NULL, NULL }; + } else { + MonoObject *target_managed = GDMonoUtils::unmanaged_get_managed(p_callable.get_object()); + MonoObject *method_string_name_managed = GDMonoUtils::create_managed_from(p_callable.get_method()); + return { target_managed, method_string_name_managed, NULL }; + } +} + +Signal managed_to_signal_info(const M_SignalInfo &p_managed_signal) { + Object *owner = p_managed_signal.owner ? + unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_signal.owner)) : + NULL; + StringName *name_ptr = unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_signal.name_string_name)); + StringName name = name_ptr ? *name_ptr : StringName(); + return Signal(owner, name); +} + +M_SignalInfo signal_info_to_managed(const Signal &p_signal) { + Object *owner = p_signal.get_object(); + MonoObject *owner_managed = GDMonoUtils::unmanaged_get_managed(owner); + MonoObject *name_string_name_managed = GDMonoUtils::create_managed_from(p_signal.get_name()); + return { owner_managed, name_string_name_managed }; +} + } // namespace GDMonoMarshal diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index 5db59522ce..7d09f46b00 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -33,6 +33,7 @@ #include "core/variant.h" +#include "../managed_callable.h" #include "gd_mono.h" #include "gd_mono_utils.h" @@ -62,7 +63,7 @@ T *unbox_addr(MonoObject *p_obj) { #define BOX_PTR(x) mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(IntPtr), x) #define BOX_ENUM(m_enum_class, x) mono_value_box(mono_domain_get(), m_enum_class, &x) -Variant::Type managed_to_variant_type(const ManagedType &p_type); +Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_variant = NULL); bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_elem_type); bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, ManagedType &r_key_type, ManagedType &r_value_type); @@ -132,6 +133,11 @@ Array mono_array_to_Array(MonoArray *p_array); MonoArray *PackedInt32Array_to_mono_array(const PackedInt32Array &p_array); PackedInt32Array mono_array_to_PackedInt32Array(MonoArray *p_array); +// PackedInt64Array + +MonoArray *PackedInt64Array_to_mono_array(const PackedInt64Array &p_array); +PackedInt64Array mono_array_to_PackedInt64Array(MonoArray *p_array); + // PackedByteArray MonoArray *PackedByteArray_to_mono_array(const PackedByteArray &p_array); @@ -142,6 +148,11 @@ PackedByteArray mono_array_to_PackedByteArray(MonoArray *p_array); MonoArray *PackedFloat32Array_to_mono_array(const PackedFloat32Array &p_array); PackedFloat32Array mono_array_to_PackedFloat32Array(MonoArray *p_array); +// PackedFloat64Array + +MonoArray *PackedFloat64Array_to_mono_array(const PackedFloat64Array &p_array); +PackedFloat64Array mono_array_to_PackedFloat64Array(MonoArray *p_array); + // PackedStringArray MonoArray *PackedStringArray_to_mono_array(const PackedStringArray &p_array); @@ -162,11 +173,36 @@ PackedVector2Array mono_array_to_PackedVector2Array(MonoArray *p_array); MonoArray *PackedVector3Array_to_mono_array(const PackedVector3Array &p_array); PackedVector3Array mono_array_to_PackedVector3Array(MonoArray *p_array); +#pragma pack(push, 1) + +struct M_Callable { + MonoObject *target; + MonoObject *method_string_name; + MonoDelegate *delegate; +}; + +struct M_SignalInfo { + MonoObject *owner; + MonoObject *name_string_name; +}; + +#pragma pack(pop) + +// Callable +Callable managed_to_callable(const M_Callable &p_managed_callable); +M_Callable callable_to_managed(const Callable &p_callable); + +// SignalInfo +Signal managed_to_signal_info(const M_SignalInfo &p_managed_signal); +M_SignalInfo signal_info_to_managed(const Signal &p_signal); + // Structures namespace InteropLayout { enum { + MATCHES_int = (sizeof(int32_t) == sizeof(uint32_t)), + MATCHES_float = (sizeof(float) == sizeof(uint32_t)), MATCHES_double = (sizeof(double) == sizeof(uint64_t)), @@ -181,10 +217,18 @@ enum { offsetof(Vector2, x) == (sizeof(real_t) * 0) && offsetof(Vector2, y) == (sizeof(real_t) * 1)), + MATCHES_Vector2i = (MATCHES_int && (sizeof(Vector2i) == (sizeof(int32_t) * 2)) && + offsetof(Vector2i, x) == (sizeof(int32_t) * 0) && + offsetof(Vector2i, y) == (sizeof(int32_t) * 1)), + MATCHES_Rect2 = (MATCHES_Vector2 && (sizeof(Rect2) == (sizeof(Vector2) * 2)) && offsetof(Rect2, position) == (sizeof(Vector2) * 0) && offsetof(Rect2, size) == (sizeof(Vector2) * 1)), + MATCHES_Rect2i = (MATCHES_Vector2i && (sizeof(Rect2i) == (sizeof(Vector2i) * 2)) && + offsetof(Rect2i, position) == (sizeof(Vector2i) * 0) && + offsetof(Rect2i, size) == (sizeof(Vector2i) * 1)), + MATCHES_Transform2D = (MATCHES_Vector2 && (sizeof(Transform2D) == (sizeof(Vector2) * 3))), // No field offset required, it stores an array MATCHES_Vector3 = (MATCHES_real_t && (sizeof(Vector3) == (sizeof(real_t) * 3)) && @@ -192,6 +236,11 @@ enum { offsetof(Vector3, y) == (sizeof(real_t) * 1) && offsetof(Vector3, z) == (sizeof(real_t) * 2)), + MATCHES_Vector3i = (MATCHES_int && (sizeof(Vector3i) == (sizeof(int32_t) * 3)) && + offsetof(Vector3i, x) == (sizeof(int32_t) * 0) && + offsetof(Vector3i, y) == (sizeof(int32_t) * 1) && + offsetof(Vector3i, z) == (sizeof(int32_t) * 2)), + MATCHES_Basis = (MATCHES_Vector3 && (sizeof(Basis) == (sizeof(Vector3) * 3))), // No field offset required, it stores an array MATCHES_Quat = (MATCHES_real_t && (sizeof(Quat) == (sizeof(real_t) * 4)) && @@ -222,8 +271,9 @@ enum { // In the future we may force this if we want to ref return these structs #ifdef GD_MONO_FORCE_INTEROP_STRUCT_COPY /* clang-format off */ -GD_STATIC_ASSERT(MATCHES_Vector2 && MATCHES_Rect2 && MATCHES_Transform2D && MATCHES_Vector3 && - MATCHES_Basis && MATCHES_Quat && MATCHES_Transform && MATCHES_AABB && MATCHES_Color &&MATCHES_Plane); +static_assert(MATCHES_Vector2 && MATCHES_Rect2 && MATCHES_Transform2D && MATCHES_Vector3 && + MATCHES_Basis && MATCHES_Quat && MATCHES_Transform && MATCHES_AABB && MATCHES_Color && + MATCHES_Plane && MATCHES_Vector2i && MATCHES_Rect2i && MATCHES_Vector3i); /* clang-format on */ #endif @@ -244,6 +294,19 @@ struct M_Vector2 { } }; +struct M_Vector2i { + int32_t x, y; + + static _FORCE_INLINE_ Vector2i convert_to(const M_Vector2i &p_from) { + return Vector2i(p_from.x, p_from.y); + } + + static _FORCE_INLINE_ M_Vector2i convert_from(const Vector2i &p_from) { + M_Vector2i ret = { p_from.x, p_from.y }; + return ret; + } +}; + struct M_Rect2 { M_Vector2 position; M_Vector2 size; @@ -259,6 +322,21 @@ struct M_Rect2 { } }; +struct M_Rect2i { + M_Vector2i position; + M_Vector2i size; + + static _FORCE_INLINE_ Rect2i convert_to(const M_Rect2i &p_from) { + return Rect2i(M_Vector2i::convert_to(p_from.position), + M_Vector2i::convert_to(p_from.size)); + } + + static _FORCE_INLINE_ M_Rect2i convert_from(const Rect2i &p_from) { + M_Rect2i ret = { M_Vector2i::convert_from(p_from.position), M_Vector2i::convert_from(p_from.size) }; + return ret; + } +}; + struct M_Transform2D { M_Vector2 elements[3]; @@ -291,6 +369,19 @@ struct M_Vector3 { } }; +struct M_Vector3i { + int32_t x, y, z; + + static _FORCE_INLINE_ Vector3i convert_to(const M_Vector3i &p_from) { + return Vector3i(p_from.x, p_from.y, p_from.z); + } + + static _FORCE_INLINE_ M_Vector3i convert_from(const Vector3i &p_from) { + M_Vector3i ret = { p_from.x, p_from.y, p_from.z }; + return ret; + } +}; + struct M_Basis { M_Vector3 elements[3]; @@ -416,9 +507,12 @@ struct M_Plane { } DECL_TYPE_MARSHAL_TEMPLATES(Vector2) +DECL_TYPE_MARSHAL_TEMPLATES(Vector2i) DECL_TYPE_MARSHAL_TEMPLATES(Rect2) +DECL_TYPE_MARSHAL_TEMPLATES(Rect2i) DECL_TYPE_MARSHAL_TEMPLATES(Transform2D) DECL_TYPE_MARSHAL_TEMPLATES(Vector3) +DECL_TYPE_MARSHAL_TEMPLATES(Vector3i) DECL_TYPE_MARSHAL_TEMPLATES(Basis) DECL_TYPE_MARSHAL_TEMPLATES(Quat) DECL_TYPE_MARSHAL_TEMPLATES(Transform) diff --git a/modules/mono/mono_gd/gd_mono_method.cpp b/modules/mono/mono_gd/gd_mono_method.cpp index 971c5ac737..e6a1ec2697 100644 --- a/modules/mono/mono_gd/gd_mono_method.cpp +++ b/modules/mono/mono_gd/gd_mono_method.cpp @@ -101,50 +101,41 @@ IMonoClassMember::Visibility GDMonoMethod::get_visibility() { } } -MonoObject *GDMonoMethod::invoke(MonoObject *p_object, const Variant **p_params, MonoException **r_exc) { - if (get_return_type().type_encoding != MONO_TYPE_VOID || get_parameters_count() > 0) { - MonoArray *params = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), get_parameters_count()); +MonoObject *GDMonoMethod::invoke(MonoObject *p_object, const Variant **p_params, MonoException **r_exc) const { + MonoException *exc = NULL; + MonoObject *ret; + + if (params_count > 0) { + MonoArray *params = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), params_count); for (int i = 0; i < params_count; i++) { MonoObject *boxed_param = GDMonoMarshal::variant_to_mono_object(p_params[i], param_types[i]); mono_array_setref(params, i, boxed_param); } - MonoException *exc = NULL; - MonoObject *ret = GDMonoUtils::runtime_invoke_array(mono_method, p_object, params, &exc); - - if (exc) { - ret = NULL; - if (r_exc) { - *r_exc = exc; - } else { - GDMonoUtils::set_pending_exception(exc); - } - } - - return ret; + ret = GDMonoUtils::runtime_invoke_array(mono_method, p_object, params, &exc); } else { - MonoException *exc = NULL; - GDMonoUtils::runtime_invoke(mono_method, p_object, NULL, &exc); - - if (exc) { - if (r_exc) { - *r_exc = exc; - } else { - GDMonoUtils::set_pending_exception(exc); - } - } + ret = GDMonoUtils::runtime_invoke(mono_method, p_object, NULL, &exc); + } - return NULL; + if (exc) { + ret = NULL; + if (r_exc) { + *r_exc = exc; + } else { + GDMonoUtils::set_pending_exception(exc); + } } + + return ret; } -MonoObject *GDMonoMethod::invoke(MonoObject *p_object, MonoException **r_exc) { +MonoObject *GDMonoMethod::invoke(MonoObject *p_object, MonoException **r_exc) const { ERR_FAIL_COND_V(get_parameters_count() > 0, NULL); return invoke_raw(p_object, NULL, r_exc); } -MonoObject *GDMonoMethod::invoke_raw(MonoObject *p_object, void **p_params, MonoException **r_exc) { +MonoObject *GDMonoMethod::invoke_raw(MonoObject *p_object, void **p_params, MonoException **r_exc) const { MonoException *exc = NULL; MonoObject *ret = GDMonoUtils::runtime_invoke(mono_method, p_object, p_params, &exc); @@ -247,7 +238,7 @@ void GDMonoMethod::get_parameter_names(Vector<StringName> &names) const { } void GDMonoMethod::get_parameter_types(Vector<ManagedType> &types) const { - for (int i = 0; i < param_types.size(); ++i) { + for (int i = 0; i < params_count; ++i) { types.push_back(param_types[i]); } } @@ -256,13 +247,22 @@ const MethodInfo &GDMonoMethod::get_method_info() { if (!method_info_fetched) { method_info.name = name; - method_info.return_val = PropertyInfo(GDMonoMarshal::managed_to_variant_type(return_type), ""); + + bool nil_is_variant = false; + method_info.return_val = PropertyInfo(GDMonoMarshal::managed_to_variant_type(return_type, &nil_is_variant), ""); + if (method_info.return_val.type == Variant::NIL && nil_is_variant) + method_info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; Vector<StringName> names; get_parameter_names(names); for (int i = 0; i < params_count; ++i) { - method_info.arguments.push_back(PropertyInfo(GDMonoMarshal::managed_to_variant_type(param_types[i]), names[i])); + nil_is_variant = false; + PropertyInfo arg_info = PropertyInfo(GDMonoMarshal::managed_to_variant_type(param_types[i], &nil_is_variant), names[i]); + if (arg_info.type == Variant::NIL && nil_is_variant) + arg_info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + + method_info.arguments.push_back(arg_info); } // TODO: default arguments diff --git a/modules/mono/mono_gd/gd_mono_method.h b/modules/mono/mono_gd/gd_mono_method.h index b47e42dec2..d4379f41fe 100644 --- a/modules/mono/mono_gd/gd_mono_method.h +++ b/modules/mono/mono_gd/gd_mono_method.h @@ -57,28 +57,28 @@ class GDMonoMethod : public IMonoClassMember { MonoMethod *mono_method; public: - virtual GDMonoClass *get_enclosing_class() const GD_FINAL; + virtual GDMonoClass *get_enclosing_class() const final; - virtual MemberType get_member_type() const GD_FINAL { return MEMBER_TYPE_METHOD; } + virtual MemberType get_member_type() const final { return MEMBER_TYPE_METHOD; } - virtual StringName get_name() const GD_FINAL { return name; } + virtual StringName get_name() const final { return name; } - virtual bool is_static() GD_FINAL; + virtual bool is_static() final; - virtual Visibility get_visibility() GD_FINAL; + virtual Visibility get_visibility() final; - virtual bool has_attribute(GDMonoClass *p_attr_class) GD_FINAL; - virtual MonoObject *get_attribute(GDMonoClass *p_attr_class) GD_FINAL; + virtual bool has_attribute(GDMonoClass *p_attr_class) final; + virtual MonoObject *get_attribute(GDMonoClass *p_attr_class) final; void fetch_attributes(); - _FORCE_INLINE_ MonoMethod *get_mono_ptr() { return mono_method; } + _FORCE_INLINE_ MonoMethod *get_mono_ptr() const { return mono_method; } - _FORCE_INLINE_ int get_parameters_count() { return params_count; } - _FORCE_INLINE_ ManagedType get_return_type() { return return_type; } + _FORCE_INLINE_ int get_parameters_count() const { return params_count; } + _FORCE_INLINE_ ManagedType get_return_type() const { return return_type; } - MonoObject *invoke(MonoObject *p_object, const Variant **p_params, MonoException **r_exc = NULL); - MonoObject *invoke(MonoObject *p_object, MonoException **r_exc = NULL); - MonoObject *invoke_raw(MonoObject *p_object, void **p_params, MonoException **r_exc = NULL); + MonoObject *invoke(MonoObject *p_object, const Variant **p_params, MonoException **r_exc = NULL) const; + MonoObject *invoke(MonoObject *p_object, MonoException **r_exc = NULL) const; + MonoObject *invoke_raw(MonoObject *p_object, void **p_params, MonoException **r_exc = NULL) const; String get_full_name(bool p_signature = false) const; String get_full_name_no_class() const; diff --git a/modules/mono/mono_gd/gd_mono_property.h b/modules/mono/mono_gd/gd_mono_property.h index 692037f76a..2aec64f565 100644 --- a/modules/mono/mono_gd/gd_mono_property.h +++ b/modules/mono/mono_gd/gd_mono_property.h @@ -47,17 +47,17 @@ class GDMonoProperty : public IMonoClassMember { MonoCustomAttrInfo *attributes; public: - virtual GDMonoClass *get_enclosing_class() const GD_FINAL { return owner; } + virtual GDMonoClass *get_enclosing_class() const final { return owner; } - virtual MemberType get_member_type() const GD_FINAL { return MEMBER_TYPE_PROPERTY; } + virtual MemberType get_member_type() const final { return MEMBER_TYPE_PROPERTY; } - virtual StringName get_name() const GD_FINAL { return name; } + virtual StringName get_name() const final { return name; } - virtual bool is_static() GD_FINAL; - virtual Visibility get_visibility() GD_FINAL; + virtual bool is_static() final; + virtual Visibility get_visibility() final; - virtual bool has_attribute(GDMonoClass *p_attr_class) GD_FINAL; - virtual MonoObject *get_attribute(GDMonoClass *p_attr_class) GD_FINAL; + virtual bool has_attribute(GDMonoClass *p_attr_class) final; + virtual MonoObject *get_attribute(GDMonoClass *p_attr_class) final; void fetch_attributes(); bool has_getter(); diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index bc290f3a7f..cdb26ae61b 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -86,10 +86,9 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) { } } - Ref<MonoGCHandle> &gchandle = script_binding.gchandle; - ERR_FAIL_COND_V(gchandle.is_null(), NULL); + MonoGCHandleData &gchandle = script_binding.gchandle; - MonoObject *target = gchandle->get_target(); + MonoObject *target = gchandle.get_target(); if (target) return target; @@ -106,7 +105,7 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) { MonoObject *mono_object = GDMonoUtils::create_managed_for_godot_object(script_binding.wrapper_class, script_binding.type_name, unmanaged); ERR_FAIL_NULL_V(mono_object, NULL); - gchandle->set_handle(MonoGCHandle::new_strong_handle(mono_object), MonoGCHandle::STRONG_HANDLE); + gchandle = MonoGCHandleData::new_strong_handle(mono_object); // Tie managed to unmanaged Reference *ref = Object::cast_to<Reference>(unmanaged); @@ -156,12 +155,35 @@ bool is_thread_attached() { return mono_domain_get() != NULL; } +uint32_t new_strong_gchandle(MonoObject *p_object) { + return mono_gchandle_new(p_object, /* pinned: */ false); +} + +uint32_t new_strong_gchandle_pinned(MonoObject *p_object) { + return mono_gchandle_new(p_object, /* pinned: */ true); +} + +uint32_t new_weak_gchandle(MonoObject *p_object) { + return mono_gchandle_new_weakref(p_object, /* track_resurrection: */ false); +} + +void free_gchandle(uint32_t p_gchandle) { + mono_gchandle_free(p_gchandle); +} + void runtime_object_init(MonoObject *p_this_obj, GDMonoClass *p_class, MonoException **r_exc) { GDMonoMethod *ctor = p_class->get_method(".ctor", 0); ERR_FAIL_NULL(ctor); ctor->invoke_raw(p_this_obj, NULL, r_exc); } +bool mono_delegate_equal(MonoDelegate *p_a, MonoDelegate *p_b) { + MonoException *exc = NULL; + MonoBoolean res = CACHED_METHOD_THUNK(Delegate, Equals).invoke((MonoObject *)p_a, (MonoObject *)p_b, &exc); + UNHANDLED_EXCEPTION(exc); + return (bool)res; +} + GDMonoClass *get_object_class(MonoObject *p_object) { return GDMono::get_singleton()->get_class(mono_object_get_class(p_object)); } @@ -220,6 +242,18 @@ MonoObject *create_managed_for_godot_object(GDMonoClass *p_class, const StringNa return mono_object; } +MonoObject *create_managed_from(const StringName &p_from) { + MonoObject *mono_object = mono_object_new(mono_domain_get(), CACHED_CLASS_RAW(StringName)); + ERR_FAIL_NULL_V(mono_object, NULL); + + // Construct + GDMonoUtils::runtime_object_init(mono_object, CACHED_CLASS(StringName)); + + CACHED_FIELD(StringName, ptr)->set_value_raw(mono_object, memnew(StringName(p_from))); + + return mono_object; +} + MonoObject *create_managed_from(const NodePath &p_from) { MonoObject *mono_object = mono_object_new(mono_domain_get(), CACHED_CLASS_RAW(NodePath)); ERR_FAIL_NULL_V(mono_object, NULL); @@ -362,7 +396,11 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) { return; } - _TLS_RECURSION_GUARD_; + static thread_local bool _recursion_flag_ = false; + if (_recursion_flag_) + return; + _recursion_flag_ = true; + SCOPE_EXIT { _recursion_flag_ = false; }; ScriptLanguage::StackInfo separator; separator.file = String(); @@ -439,8 +477,7 @@ void set_pending_exception(MonoException *p_exc) { #endif } -_THREAD_LOCAL_(int) -current_invoke_count = 0; +thread_local int current_invoke_count = 0; MonoObject *runtime_invoke(MonoMethod *p_method, void *p_obj, void **p_params, MonoException **r_exc) { GD_MONO_BEGIN_RUNTIME_INVOKE; @@ -644,6 +681,10 @@ ScopeThreadAttach::~ScopeThreadAttach() { } } -// namespace Marshal +StringName get_native_godot_class_name(GDMonoClass *p_class) { + MonoObject *native_name_obj = p_class->get_field(BINDINGS_NATIVE_NAME_FIELD)->get_value(NULL); + StringName *ptr = GDMonoMarshal::unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(native_name_obj)); + return ptr ? *ptr : StringName(); +} } // namespace GDMonoUtils diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h index db9f99bfdc..fd02907d87 100644 --- a/modules/mono/mono_gd/gd_mono_utils.h +++ b/modules/mono/mono_gd/gd_mono_utils.h @@ -35,7 +35,6 @@ #include "../mono_gc_handle.h" #include "../utils/macros.h" -#include "../utils/thread_local.h" #include "gd_mono_header.h" #include "core/object.h" @@ -93,14 +92,22 @@ _FORCE_INLINE_ bool is_main_thread() { return mono_domain_get() != NULL && mono_thread_get_main() == mono_thread_current(); } +uint32_t new_strong_gchandle(MonoObject *p_object); +uint32_t new_strong_gchandle_pinned(MonoObject *p_object); +uint32_t new_weak_gchandle(MonoObject *p_object); +void free_gchandle(uint32_t p_gchandle); + void runtime_object_init(MonoObject *p_this_obj, GDMonoClass *p_class, MonoException **r_exc = NULL); +bool mono_delegate_equal(MonoDelegate *p_a, MonoDelegate *p_b); + GDMonoClass *get_object_class(MonoObject *p_object); GDMonoClass *type_get_proxy_class(const StringName &p_type); GDMonoClass *get_class_native_base(GDMonoClass *p_class); MonoObject *create_managed_for_godot_object(GDMonoClass *p_class, const StringName &p_native, Object *p_object); +MonoObject *create_managed_from(const StringName &p_from); MonoObject *create_managed_from(const NodePath &p_from); MonoObject *create_managed_from(const RID &p_from); MonoObject *create_managed_from(const Array &p_from, GDMonoClass *p_class); @@ -123,7 +130,7 @@ void print_unhandled_exception(MonoException *p_exc); */ void set_pending_exception(MonoException *p_exc); -extern _THREAD_LOCAL_(int) current_invoke_count; +extern thread_local int current_invoke_count; _FORCE_INLINE_ int get_runtime_invoke_count() { return current_invoke_count; @@ -152,9 +159,11 @@ private: MonoThread *mono_thread; }; +StringName get_native_godot_class_name(GDMonoClass *p_class); + } // namespace GDMonoUtils -#define NATIVE_GDMONOCLASS_NAME(m_class) (GDMonoMarshal::mono_string_to_godot((MonoString *)m_class->get_field(BINDINGS_NATIVE_NAME_FIELD)->get_value(NULL))) +#define NATIVE_GDMONOCLASS_NAME(m_class) (GDMonoUtils::get_native_godot_class_name(m_class)) #define GD_MONO_BEGIN_RUNTIME_INVOKE \ int &_runtime_invoke_count_ref = GDMonoUtils::get_runtime_invoke_count_ref(); \ diff --git a/modules/mono/signal_awaiter_utils.cpp b/modules/mono/signal_awaiter_utils.cpp index 718bc2bb93..25e5a41215 100644 --- a/modules/mono/signal_awaiter_utils.cpp +++ b/modules/mono/signal_awaiter_utils.cpp @@ -36,103 +36,192 @@ #include "mono_gd/gd_mono_marshal.h" #include "mono_gd/gd_mono_utils.h" -namespace SignalAwaiterUtils { - -Error connect_signal_awaiter(Object *p_source, const String &p_signal, Object *p_target, MonoObject *p_awaiter) { - +Error gd_mono_connect_signal_awaiter(Object *p_source, const StringName &p_signal, Object *p_target, MonoObject *p_awaiter) { ERR_FAIL_NULL_V(p_source, ERR_INVALID_DATA); ERR_FAIL_NULL_V(p_target, ERR_INVALID_DATA); - Ref<SignalAwaiterHandle> sa_con = memnew(SignalAwaiterHandle(p_awaiter)); -#ifdef DEBUG_ENABLED - sa_con->set_connection_target(p_target); -#endif + // TODO: Use pooling for ManagedCallable instances. + SignalAwaiterCallable *awaiter_callable = memnew(SignalAwaiterCallable(p_target, p_awaiter, p_signal)); + Callable callable = Callable(awaiter_callable); + + return p_source->connect(p_signal, callable, Vector<Variant>(), Object::CONNECT_ONESHOT); +} + +bool SignalAwaiterCallable::compare_equal(const CallableCustom *p_a, const CallableCustom *p_b) { + const SignalAwaiterCallable *a = static_cast<const SignalAwaiterCallable *>(p_a); + const SignalAwaiterCallable *b = static_cast<const SignalAwaiterCallable *>(p_b); - Vector<Variant> binds; - binds.push_back(sa_con); + if (a->target_id != b->target_id) + return false; + + if (a->signal != b->signal) + return false; + + return true; +} + +bool SignalAwaiterCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) { + if (compare_equal(p_a, p_b)) + return false; + return p_a < p_b; +} + +uint32_t SignalAwaiterCallable::hash() const { + uint32_t hash = signal.hash(); + return hash_djb2_one_64(target_id, hash); +} - Error err = p_source->connect_compat(p_signal, sa_con.ptr(), - CSharpLanguage::get_singleton()->get_string_names()._signal_callback, - binds, Object::CONNECT_ONESHOT); +String SignalAwaiterCallable::get_as_text() const { + Object *base = ObjectDB::get_instance(target_id); + if (base) { + String class_name = base->get_class(); + Ref<Script> script = base->get_script(); + if (script.is_valid() && script->get_path().is_resource_file()) { - if (err != OK) { - // Set it as completed to prevent it from calling the failure callback when released. - // The awaiter will be aware of the failure by checking the returned error. - sa_con->set_completed(true); + class_name += "(" + script->get_path().get_file() + ")"; + } + return class_name + "::SignalAwaiterMiddleman::" + String(signal); + } else { + return "null::SignalAwaiterMiddleman::" + String(signal); } +} - return err; +CallableCustom::CompareEqualFunc SignalAwaiterCallable::get_compare_equal_func() const { + return compare_equal_func_ptr; } -} // namespace SignalAwaiterUtils -Variant SignalAwaiterHandle::_signal_callback(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { +CallableCustom::CompareLessFunc SignalAwaiterCallable::get_compare_less_func() const { + return compare_less_func_ptr; +} + +ObjectID SignalAwaiterCallable::get_object() const { + return target_id; +} + +void SignalAwaiterCallable::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const { + r_call_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; // Can't find anything better + r_return_value = Variant(); #ifdef DEBUG_ENABLED - ERR_FAIL_COND_V_MSG(conn_target_id.is_valid() && !ObjectDB::get_instance(conn_target_id), Variant(), + ERR_FAIL_COND_MSG(target_id.is_valid() && !ObjectDB::get_instance(target_id), "Resumed after await, but class instance is gone."); #endif - if (p_argcount < 1) { - r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; - r_error.argument = 1; - return Variant(); - } + MonoArray *signal_args = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), p_argcount); - Ref<SignalAwaiterHandle> self = *p_args[p_argcount - 1]; - - if (self.is_null()) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = p_argcount - 1; - r_error.expected = Variant::OBJECT; - return Variant(); + for (int i = 0; i < p_argcount; i++) { + MonoObject *boxed = GDMonoMarshal::variant_to_mono_object(*p_arguments[i]); + mono_array_setref(signal_args, i, boxed); } - set_completed(true); - - int signal_argc = p_argcount - 1; - MonoArray *signal_args = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), signal_argc); + MonoObject *awaiter = awaiter_handle.get_target(); - for (int i = 0; i < signal_argc; i++) { - MonoObject *boxed = GDMonoMarshal::variant_to_mono_object(*p_args[i]); - mono_array_setref(signal_args, i, boxed); + if (!awaiter) { + r_call_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; + return; } MonoException *exc = NULL; - GD_MONO_BEGIN_RUNTIME_INVOKE; - CACHED_METHOD_THUNK(SignalAwaiter, SignalCallback).invoke(get_target(), signal_args, &exc); - GD_MONO_END_RUNTIME_INVOKE; + CACHED_METHOD_THUNK(SignalAwaiter, SignalCallback).invoke(awaiter, signal_args, &exc); if (exc) { GDMonoUtils::set_pending_exception(exc); - ERR_FAIL_V(Variant()); + ERR_FAIL(); + } else { + r_call_error.error = Callable::CallError::CALL_OK; + } +} + +SignalAwaiterCallable::SignalAwaiterCallable(Object *p_target, MonoObject *p_awaiter, const StringName &p_signal) : + target_id(p_target->get_instance_id()), + awaiter_handle(MonoGCHandleData::new_strong_handle(p_awaiter)), + signal(p_signal) { +} + +SignalAwaiterCallable::~SignalAwaiterCallable() { + awaiter_handle.release(); +} + +bool EventSignalCallable::compare_equal(const CallableCustom *p_a, const CallableCustom *p_b) { + const EventSignalCallable *a = static_cast<const EventSignalCallable *>(p_a); + const EventSignalCallable *b = static_cast<const EventSignalCallable *>(p_b); + + if (a->owner != b->owner) + return false; + + if (a->event_signal != b->event_signal) + return false; + + return true; +} + +bool EventSignalCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) { + if (compare_equal(p_a, p_b)) + return false; + return p_a < p_b; +} + +uint32_t EventSignalCallable::hash() const { + uint32_t hash = event_signal->field->get_name().hash(); + return hash_djb2_one_64(owner->get_instance_id(), hash); +} + +String EventSignalCallable::get_as_text() const { + String class_name = owner->get_class(); + Ref<Script> script = owner->get_script(); + if (script.is_valid() && script->get_path().is_resource_file()) { + class_name += "(" + script->get_path().get_file() + ")"; } + StringName signal = event_signal->field->get_name(); + return class_name + "::EventSignalMiddleman::" + String(signal); +} - return Variant(); +CallableCustom::CompareEqualFunc EventSignalCallable::get_compare_equal_func() const { + return compare_equal_func_ptr; } -void SignalAwaiterHandle::_bind_methods() { +CallableCustom::CompareLessFunc EventSignalCallable::get_compare_less_func() const { + return compare_less_func_ptr; +} - ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "_signal_callback", &SignalAwaiterHandle::_signal_callback, MethodInfo("_signal_callback")); +ObjectID EventSignalCallable::get_object() const { + return owner->get_instance_id(); } -SignalAwaiterHandle::SignalAwaiterHandle(MonoObject *p_managed) : - MonoGCHandle(MonoGCHandle::new_strong_handle(p_managed), STRONG_HANDLE) {} +StringName EventSignalCallable::get_signal() const { + return event_signal->field->get_name(); +} -SignalAwaiterHandle::~SignalAwaiterHandle() { +void EventSignalCallable::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const { + r_call_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; // Can't find anything better + r_return_value = Variant(); - if (!completed) { - MonoObject *awaiter = get_target(); + ERR_FAIL_COND(p_argcount < event_signal->invoke_method->get_parameters_count()); - if (awaiter) { - MonoException *exc = NULL; - GD_MONO_BEGIN_RUNTIME_INVOKE; - CACHED_METHOD_THUNK(SignalAwaiter, FailureCallback).invoke(awaiter, &exc); - GD_MONO_END_RUNTIME_INVOKE; + CSharpInstance *csharp_instance = CAST_CSHARP_INSTANCE(owner->get_script_instance()); + ERR_FAIL_NULL(csharp_instance); - if (exc) { - GDMonoUtils::set_pending_exception(exc); - ERR_FAIL(); - } - } + MonoObject *owner_managed = csharp_instance->get_mono_object(); + ERR_FAIL_NULL(owner_managed); + + MonoObject *delegate_field_value = event_signal->field->get_value(owner_managed); + if (!delegate_field_value) { + r_call_error.error = Callable::CallError::CALL_OK; + return; } + + MonoException *exc = NULL; + event_signal->invoke_method->invoke(delegate_field_value, p_arguments, &exc); + + if (exc) { + GDMonoUtils::set_pending_exception(exc); + ERR_FAIL(); + } else { + r_call_error.error = Callable::CallError::CALL_OK; + } +} + +EventSignalCallable::EventSignalCallable(Object *p_owner, const CSharpScript::EventSignal *p_event_signal) : + owner(p_owner), + event_signal(p_event_signal) { } diff --git a/modules/mono/signal_awaiter_utils.h b/modules/mono/signal_awaiter_utils.h index 012f6e5bb3..c550315a23 100644 --- a/modules/mono/signal_awaiter_utils.h +++ b/modules/mono/signal_awaiter_utils.h @@ -32,40 +32,66 @@ #define SIGNAL_AWAITER_UTILS_H #include "core/reference.h" + +#include "csharp_script.h" #include "mono_gc_handle.h" -namespace SignalAwaiterUtils { +Error gd_mono_connect_signal_awaiter(Object *p_source, const StringName &p_signal, Object *p_target, MonoObject *p_awaiter); + +class SignalAwaiterCallable : public CallableCustom { + ObjectID target_id; + MonoGCHandleData awaiter_handle; + StringName signal; + +public: + static bool compare_equal(const CallableCustom *p_a, const CallableCustom *p_b); + static bool compare_less(const CallableCustom *p_a, const CallableCustom *p_b); -Error connect_signal_awaiter(Object *p_source, const String &p_signal, Object *p_target, MonoObject *p_awaiter); -} + static constexpr CompareEqualFunc compare_equal_func_ptr = &SignalAwaiterCallable::compare_equal; + static constexpr CompareEqualFunc compare_less_func_ptr = &SignalAwaiterCallable::compare_less; -class SignalAwaiterHandle : public MonoGCHandle { + uint32_t hash() const override; - GDCLASS(SignalAwaiterHandle, MonoGCHandle); + String get_as_text() const override; - bool completed; + CompareEqualFunc get_compare_equal_func() const override; + CompareLessFunc get_compare_less_func() const override; -#ifdef DEBUG_ENABLED - ObjectID conn_target_id; -#endif + ObjectID get_object() const override; - Variant _signal_callback(const Variant **p_args, int p_argcount, Callable::CallError &r_error); + _FORCE_INLINE_ StringName get_signal() const { return signal; } + + void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override; + + SignalAwaiterCallable(Object *p_target, MonoObject *p_awaiter, const StringName &p_signal); + ~SignalAwaiterCallable(); +}; -protected: - static void _bind_methods(); +class EventSignalCallable : public CallableCustom { + Object *owner; + const CSharpScript::EventSignal *event_signal; public: - _FORCE_INLINE_ bool is_completed() { return completed; } - _FORCE_INLINE_ void set_completed(bool p_completed) { completed = p_completed; } + static bool compare_equal(const CallableCustom *p_a, const CallableCustom *p_b); + static bool compare_less(const CallableCustom *p_a, const CallableCustom *p_b); + + static constexpr CompareEqualFunc compare_equal_func_ptr = &EventSignalCallable::compare_equal; + static constexpr CompareEqualFunc compare_less_func_ptr = &EventSignalCallable::compare_less; + + uint32_t hash() const override; + + String get_as_text() const override; + + CompareEqualFunc get_compare_equal_func() const override; + CompareLessFunc get_compare_less_func() const override; + + ObjectID get_object() const override; + + StringName get_signal() const; -#ifdef DEBUG_ENABLED - _FORCE_INLINE_ void set_connection_target(Object *p_target) { - conn_target_id = p_target->get_instance_id(); - } -#endif + void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override; - SignalAwaiterHandle(MonoObject *p_managed); - ~SignalAwaiterHandle(); + EventSignalCallable(Object *p_owner, const CSharpScript::EventSignal *p_event_signal); }; #endif // SIGNAL_AWAITER_UTILS_H diff --git a/modules/mono/utils/macros.h b/modules/mono/utils/macros.h index 754000dc14..8650d6cc09 100644 --- a/modules/mono/utils/macros.h +++ b/modules/mono/utils/macros.h @@ -36,38 +36,6 @@ #define _GD_VARNAME_CONCAT_(m_a, m_b, m_c) _GD_VARNAME_CONCAT_A_(m_a, m_b, m_c) #define GD_UNIQUE_NAME(m_name) _GD_VARNAME_CONCAT_(m_name, _, __COUNTER__) -// static assert -// TODO: Get rid of this macro once we upgrade to C++11 - -#ifdef __cpp_static_assert -#define GD_STATIC_ASSERT(m_cond) static_assert((m_cond), "Condition '" #m_cond "' failed") -#else -#define GD_STATIC_ASSERT(m_cond) typedef int GD_UNIQUE_NAME(godot_static_assert)[((m_cond) ? 1 : -1)] -#endif - -// final -// TODO: Get rid of this macro once we upgrade to C++11 - -#if (__cplusplus >= 201103L) -#define GD_FINAL final -#else -#define GD_FINAL -#endif - -// noreturn -// TODO: Get rid of this macro once we upgrade to C++11 - -#if (__cplusplus >= 201103L) -#define GD_NORETURN [[noreturn]] -#elif defined(__GNUC__) -#define GD_NORETURN __attribute__((noreturn)) -#elif defined(_MSC_VER) -#define GD_NORETURN __declspec(noreturn) -#else -#define GD_NORETURN -#pragma message "Macro GD_NORETURN will have no effect" -#endif - // unreachable #if defined(_MSC_VER) @@ -81,4 +49,25 @@ } while (true); #endif +namespace gdmono { + +template <typename F> +struct ScopeExit { + ScopeExit(F p_exit_func) : + exit_func(p_exit_func) {} + ~ScopeExit() { exit_func(); } + F exit_func; +}; + +class ScopeExitAux { +public: + template <typename F> + ScopeExit<F> operator+(F p_exit_func) { return ScopeExit<F>(p_exit_func); } +}; + +} // namespace gdmono + +#define SCOPE_EXIT \ + auto GD_UNIQUE_NAME(gd_scope_exit) = gdmono::ScopeExitAux() + [=]() + #endif // UTIL_MACROS_H diff --git a/modules/mono/utils/thread_local.h b/modules/mono/utils/thread_local.h deleted file mode 100644 index b1cc2e37ea..0000000000 --- a/modules/mono/utils/thread_local.h +++ /dev/null @@ -1,177 +0,0 @@ -/*************************************************************************/ -/* thread_local.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 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 THREAD_LOCAL_H -#define THREAD_LOCAL_H - -#ifdef HAVE_CXX11_THREAD_LOCAL -#define _THREAD_LOCAL_(m_t) thread_local m_t -#else - -#if !defined(__GNUC__) && !defined(_MSC_VER) -#error Platform or compiler not supported -#endif - -#if defined(__GNUC__) - -#ifdef HAVE_GCC___THREAD -#define _THREAD_LOCAL_(m_t) __thread m_t -#else -#define USE_CUSTOM_THREAD_LOCAL -#endif - -#elif defined(_MSC_VER) - -#ifdef HAVE_DECLSPEC_THREAD -#define _THREAD_LOCAL_(m_t) __declspec(thread) m_t -#else -#define USE_CUSTOM_THREAD_LOCAL -#endif - -#endif // __GNUC__ _MSC_VER - -#endif // HAVE_CXX11_THREAD_LOCAL - -#ifdef USE_CUSTOM_THREAD_LOCAL -#define _THREAD_LOCAL_(m_t) ThreadLocal<m_t> -#endif - -#include "core/typedefs.h" - -#ifdef WINDOWS_ENABLED -#define _CALLBACK_FUNC_ __stdcall -#else -#define _CALLBACK_FUNC_ -#endif - -struct ThreadLocalStorage { - - void *get_value() const; - void set_value(void *p_value) const; - - void alloc(void(_CALLBACK_FUNC_ *p_destr_callback)(void *)); - void free(); - -private: - struct Impl; - Impl *pimpl; -}; - -template <typename T> -class ThreadLocal { - - ThreadLocalStorage storage; - - T init_val; - - static void _CALLBACK_FUNC_ destr_callback(void *tls_data) { - memdelete(static_cast<T *>(tls_data)); - } - - T *_tls_get_value() const { - void *tls_data = storage.get_value(); - - if (tls_data) - return static_cast<T *>(tls_data); - - T *data = memnew(T(init_val)); - - storage.set_value(data); - - return data; - } - - void _initialize(const T &p_init_val) { - init_val = p_init_val; - storage.alloc(&destr_callback); - } - -public: - ThreadLocal() { - _initialize(T()); - } - - ThreadLocal(const T &p_init_val) { - _initialize(p_init_val); - } - - ThreadLocal(const ThreadLocal &other) { - _initialize(*other._tls_get_value()); - } - - ~ThreadLocal() { - storage.free(); - } - - _FORCE_INLINE_ T *operator&() const { - return _tls_get_value(); - } - - _FORCE_INLINE_ operator T &() const { - return *_tls_get_value(); - } - - _FORCE_INLINE_ ThreadLocal &operator=(const T &val) { - T *ptr = _tls_get_value(); - *ptr = val; - return *this; - } -}; - -struct FlagScopeGuard { - - FlagScopeGuard(bool &p_flag) : - flag(p_flag) { - flag = !flag; - } - - ~FlagScopeGuard() { - flag = !flag; - } - -private: - bool &flag; -}; - -#undef _CALLBACK_FUNC_ - -#define _TLS_RECURSION_GUARD_V_(m_ret) \ - static _THREAD_LOCAL_(bool) _recursion_flag_ = false; \ - if (_recursion_flag_) \ - return m_ret; \ - FlagScopeGuard _recursion_guard_(_recursion_flag_); - -#define _TLS_RECURSION_GUARD_ \ - static _THREAD_LOCAL_(bool) _recursion_flag_ = false; \ - if (_recursion_flag_) \ - return; \ - FlagScopeGuard _recursion_guard_(_recursion_flag_); - -#endif // THREAD_LOCAL_H diff --git a/modules/upnp/upnp.h b/modules/upnp/upnp.h index d052e155de..46f44e04e5 100644 --- a/modules/upnp/upnp.h +++ b/modules/upnp/upnp.h @@ -46,7 +46,7 @@ private: int discover_local_port; bool discover_ipv6; - Vector<Ref<UPNPDevice> > devices; + Vector<Ref<UPNPDevice>> devices; bool is_common_device(const String &dev) const; void add_device_to_list(UPNPDev *dev, UPNPDev *devlist); diff --git a/modules/vhacd/register_types.cpp b/modules/vhacd/register_types.cpp index 26c6146bab..7deb20f6e7 100644 --- a/modules/vhacd/register_types.cpp +++ b/modules/vhacd/register_types.cpp @@ -32,7 +32,7 @@ #include "scene/resources/mesh.h" #include "thirdparty/vhacd/public/VHACD.h" -static Vector<Vector<Face3> > convex_decompose(const Vector<Face3> &p_faces) { +static Vector<Vector<Face3>> convex_decompose(const Vector<Face3> &p_faces) { Vector<float> vertices; vertices.resize(p_faces.size() * 9); @@ -54,7 +54,7 @@ static Vector<Vector<Face3> > convex_decompose(const Vector<Face3> &p_faces) { int hull_count = decomposer->GetNConvexHulls(); - Vector<Vector<Face3> > ret; + Vector<Vector<Face3>> ret; for (int i = 0; i < hull_count; i++) { Vector<Face3> triangles; diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index 050fdbcb07..d00cc6986f 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -827,7 +827,7 @@ void VisualScript::rename_custom_signal(const StringName &p_name, const StringNa void VisualScript::get_custom_signal_list(List<StringName> *r_custom_signals) const { - for (const Map<StringName, Vector<Argument> >::Element *E = custom_signals.front(); E; E = E->next()) { + for (const Map<StringName, Vector<Argument>>::Element *E = custom_signals.front(); E; E = E->next()) { r_custom_signals->push_back(E->key()); } @@ -981,7 +981,7 @@ bool VisualScript::has_script_signal(const StringName &p_signal) const { void VisualScript::get_script_signal_list(List<MethodInfo> *r_signals) const { - for (const Map<StringName, Vector<Argument> >::Element *E = custom_signals.front(); E; E = E->next()) { + for (const Map<StringName, Vector<Argument>>::Element *E = custom_signals.front(); E; E = E->next()) { MethodInfo mi; mi.name = E->key(); @@ -1148,8 +1148,8 @@ StringName VisualScript::get_rset_property(const uint16_t p_rset_property_id) co } MultiplayerAPI::RPCMode VisualScript::get_rset_mode_by_id(const uint16_t p_rset_variable_id) const { - ERR_FAIL_COND_V(p_rset_variable_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED); - return rpc_functions[p_rset_variable_id].mode; + ERR_FAIL_COND_V(p_rset_variable_id >= rpc_variables.size(), MultiplayerAPI::RPC_MODE_DISABLED); + return rpc_variables[p_rset_variable_id].mode; } MultiplayerAPI::RPCMode VisualScript::get_rset_mode(const StringName &p_variable) const { @@ -1302,7 +1302,7 @@ Dictionary VisualScript::_get_data() const { d["variables"] = vars; Array sigs; - for (const Map<StringName, Vector<Argument> >::Element *E = custom_signals.front(); E; E = E->next()) { + for (const Map<StringName, Vector<Argument>>::Element *E = custom_signals.front(); E; E = E->next()) { Dictionary cs; cs["name"] = E->key(); @@ -2779,7 +2779,7 @@ void VisualScriptLanguage::get_recognized_extensions(List<String> *p_extensions) } void VisualScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const { } -void VisualScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_constants) const { +void VisualScriptLanguage::get_public_constants(List<Pair<String, Variant>> *p_constants) const { } void VisualScriptLanguage::profiling_start() { diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index d1005c025c..20273316b4 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -246,7 +246,7 @@ private: Map<StringName, Function> functions; Map<StringName, Variable> variables; - Map<StringName, Vector<Argument> > custom_signals; + Map<StringName, Vector<Argument>> custom_signals; Vector<ScriptNetData> rpc_functions; Vector<ScriptNetData> rpc_variables; @@ -623,7 +623,7 @@ public: virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual void get_public_functions(List<MethodInfo> *p_functions) const; - virtual void get_public_constants(List<Pair<String, Variant> > *p_constants) const; + virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const; virtual void profiling_start(); virtual void profiling_stop(); diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 8840b9f7cf..ca255ebf82 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -1458,7 +1458,7 @@ void VisualScriptEditor::_remove_output_port(int p_id, int p_port) { List<VisualScript::DataConnection> data_connections; script->get_data_connection_list(func, &data_connections); - HashMap<int, Set<int> > conn_map; + HashMap<int, Set<int>> conn_map; for (const List<VisualScript::DataConnection>::Element *E = data_connections.front(); E; E = E->next()) { if (E->get().from_node == p_id && E->get().from_port == p_port) { // push into the connections map @@ -3078,8 +3078,8 @@ void VisualScriptEditor::_graph_disconnected(const String &p_from, int p_from_sl void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from, const StringName &p_func_to, int p_id) { Set<int> nodes_to_move; - HashMap<int, Map<int, int> > seqconns_to_move; // from => List(outp, to) - HashMap<int, Map<int, Pair<int, int> > > dataconns_to_move; // to => List(inp_p => from, outp) + HashMap<int, Map<int, int>> seqconns_to_move; // from => List(outp, to) + HashMap<int, Map<int, Pair<int, int>>> dataconns_to_move; // to => List(inp_p => from, outp) nodes_to_move.insert(p_id); Set<int> sequence_connections; @@ -3087,7 +3087,7 @@ void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from, List<VisualScript::SequenceConnection> sequence_conns; script->get_sequence_connection_list(p_func_from, &sequence_conns); - HashMap<int, Map<int, int> > seqcons; // from => List(out_p => to) + HashMap<int, Map<int, int>> seqcons; // from => List(out_p => to) for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) { int from = E->get().from_node; @@ -3102,7 +3102,7 @@ void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from, int conn = p_id; List<int> stack; - HashMap<int, Set<int> > seen; // from, outp + HashMap<int, Set<int>> seen; // from, outp while (seqcons.has(conn)) { for (auto E = seqcons[conn].front(); E; E = E->next()) { if (seen.has(conn) && seen[conn].has(E->key())) { @@ -3139,7 +3139,7 @@ void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from, List<VisualScript::DataConnection> data_connections; script->get_data_connection_list(p_func_from, &data_connections); - HashMap<int, Map<int, Pair<int, int> > > connections; + HashMap<int, Map<int, Pair<int, int>>> connections; for (List<VisualScript::DataConnection>::Element *E = data_connections.front(); E; E = E->next()) { int from = E->get().from_node; @@ -3148,14 +3148,14 @@ void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from, int in_p = E->get().to_port; if (!connections.has(to)) - connections.set(to, Map<int, Pair<int, int> >()); + connections.set(to, Map<int, Pair<int, int>>()); connections[to].insert(in_p, Pair<int, int>(from, out_p)); } // go through the HashMap and do all sorts of crazy ass stuff now... Set<int> nodes_to_be_added; for (Set<int>::Element *F = nodes_to_move.front(); F; F = F->next()) { - HashMap<int, Set<int> > seen; + HashMap<int, Set<int>> seen; List<int> stack; int id = F->get(); while (connections.has(id)) { @@ -3190,7 +3190,7 @@ void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from, seen[id].insert(E->key()); stack.push_back(id); if (!dataconns_to_move.has(id)) - dataconns_to_move.set(id, Map<int, Pair<int, int> >()); + dataconns_to_move.set(id, Map<int, Pair<int, int>>()); dataconns_to_move[id].insert(E->key(), Pair<int, int>(E->get().first, E->get().second)); id = E->get().first; nodes_to_be_added.insert(id); @@ -3261,7 +3261,7 @@ void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from, dataconns_to_move.get_key_list(&keys); for (List<int>::Element *E = keys.front(); E; E = E->next()) { int to_node = E->get(); // to_node - for (Map<int, Pair<int, int> >::Element *F = dataconns_to_move[E->get()].front(); F; F = F->next()) { + for (Map<int, Pair<int, int>>::Element *F = dataconns_to_move[E->get()].front(); F; F = F->next()) { int inp_p = F->key(); Pair<int, int> fro = F->get(); @@ -3933,7 +3933,7 @@ void VisualScriptEditor::_notification(int p_what) { bool dark_theme = tm->get_constant("dark_theme", "Editor"); - List<Pair<String, Color> > colors; + List<Pair<String, Color>> colors; if (dark_theme) { colors.push_back(Pair<String, Color>("flow_control", Color(0.96, 0.96, 0.96))); colors.push_back(Pair<String, Color>("functions", Color(0.96, 0.52, 0.51))); @@ -3950,7 +3950,7 @@ void VisualScriptEditor::_notification(int p_what) { colors.push_back(Pair<String, Color>("constants", Color(0.94, 0.18, 0.49))); } - for (List<Pair<String, Color> >::Element *E = colors.front(); E; E = E->next()) { + for (List<Pair<String, Color>>::Element *E = colors.front(); E; E = E->next()) { Ref<StyleBoxFlat> sb = tm->get_stylebox("frame", "GraphNode"); if (!sb.is_null()) { Ref<StyleBoxFlat> frame_style = sb->duplicate(); @@ -4149,7 +4149,7 @@ void VisualScriptEditor::_menu_option(int p_what) { } } - for (Map<int, Ref<VisualScriptNode> >::Element *E = clipboard->nodes.front(); E; E = E->next()) { + for (Map<int, Ref<VisualScriptNode>>::Element *E = clipboard->nodes.front(); E; E = E->next()) { Ref<VisualScriptNode> node = E->get()->duplicate(); @@ -4196,7 +4196,7 @@ void VisualScriptEditor::_menu_option(int p_what) { case EDIT_CREATE_FUNCTION: { StringName function = ""; - Map<int, Ref<VisualScriptNode> > nodes; + Map<int, Ref<VisualScriptNode>> nodes; Set<int> selections; for (int i = 0; i < graph->get_child_count(); i++) { GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); @@ -4252,7 +4252,7 @@ void VisualScriptEditor::_menu_option(int p_what) { // the user wants to connect the nodes int top_nd = -1; Vector2 top; - for (Map<int, Ref<VisualScriptNode> >::Element *E = nodes.front(); E; E = E->next()) { + for (Map<int, Ref<VisualScriptNode>>::Element *E = nodes.front(); E; E = E->next()) { Ref<VisualScriptNode> nd = script->get_node(function, E->key()); if (nd.is_valid() && nd->has_input_sequence_port()) { if (top_nd < 0) { @@ -4316,7 +4316,7 @@ void VisualScriptEditor::_menu_option(int p_what) { } List<Variant::Type> inputs; // input types - List<Pair<int, int> > input_connections; + List<Pair<int, int>> input_connections; { List<VisualScript::DataConnection> dats; script->get_data_connection_list(function, &dats); @@ -4359,7 +4359,7 @@ void VisualScriptEditor::_menu_option(int p_what) { // Move the nodes - for (Map<int, Ref<VisualScriptNode> >::Element *E = nodes.front(); E; E = E->next()) { + for (Map<int, Ref<VisualScriptNode>>::Element *E = nodes.front(); E; E = E->next()) { undo_redo->add_do_method(script.ptr(), "remove_node", function, E->key()); undo_redo->add_do_method(script.ptr(), "add_node", new_fn, E->key(), E->get(), script->get_node_position(function, E->key())); @@ -4414,7 +4414,7 @@ void VisualScriptEditor::_menu_option(int p_what) { // * might make the system more intelligent by checking port from info. int i = 0; - List<Pair<int, int> >::Element *F = input_connections.front(); + List<Pair<int, int>>::Element *F = input_connections.front(); for (List<Variant::Type>::Element *E = inputs.front(); E && F; E = E->next(), F = F->next()) { func_node->add_argument(E->get(), "arg_" + String::num_int64(i), i); undo_redo->add_do_method(script.ptr(), "data_connect", new_fn, fn_id, i, F->get().first, F->get().second); diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h index 9a2a42b160..6ff00cf0a6 100644 --- a/modules/visual_script/visual_script_editor.h +++ b/modules/visual_script/visual_script_editor.h @@ -133,10 +133,10 @@ class VisualScriptEditor : public ScriptEditorBase { String name; Variant::Type ret; bool ret_variant; - Vector<Pair<Variant::Type, String> > args; + Vector<Pair<Variant::Type, String>> args; }; - HashMap<StringName, Ref<StyleBox> > node_styles; + HashMap<StringName, Ref<StyleBox>> node_styles; StringName edited_func; StringName default_func; @@ -153,7 +153,7 @@ class VisualScriptEditor : public ScriptEditorBase { struct Clipboard { - Map<int, Ref<VisualScriptNode> > nodes; + Map<int, Ref<VisualScriptNode>> nodes; Map<int, Vector2> nodes_positions; Set<VisualScript::SequenceConnection> sequence_connections; diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp index 23d1c8ccc0..c52315a477 100644 --- a/modules/visual_script/visual_script_expression.cpp +++ b/modules/visual_script/visual_script_expression.cpp @@ -1141,7 +1141,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() { } } - //consecutively do unary opeators + //consecutively do unary operators for (int i = expr_pos - 1; i >= next_op; i--) { OperatorNode *op = alloc_node<OperatorNode>(); diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index ea09c82013..41c1ea4ca2 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -3519,7 +3519,7 @@ VisualScriptConstructor::VisualScriptConstructor() { type = Variant::NIL; } -static Map<String, Pair<Variant::Type, MethodInfo> > constructor_map; +static Map<String, Pair<Variant::Type, MethodInfo>> constructor_map; static Ref<VisualScriptNode> create_constructor_node(const String &p_name) { diff --git a/modules/webrtc/webrtc_multiplayer.cpp b/modules/webrtc/webrtc_multiplayer.cpp index 9df2420bbc..c24ae3468f 100644 --- a/modules/webrtc/webrtc_multiplayer.cpp +++ b/modules/webrtc/webrtc_multiplayer.cpp @@ -70,7 +70,7 @@ void WebRTCMultiplayer::poll() { List<int> remove; List<int> add; - for (Map<int, Ref<ConnectedPeer> >::Element *E = peer_map.front(); E; E = E->next()) { + for (Map<int, Ref<ConnectedPeer>>::Element *E = peer_map.front(); E; E = E->next()) { Ref<ConnectedPeer> peer = E->get(); peer->connection->poll(); // Check peer state @@ -89,7 +89,7 @@ void WebRTCMultiplayer::poll() { } // Check channels state int ready = 0; - for (List<Ref<WebRTCDataChannel> >::Element *C = peer->channels.front(); C && C->get().is_valid(); C = C->next()) { + for (List<Ref<WebRTCDataChannel>>::Element *C = peer->channels.front(); C && C->get().is_valid(); C = C->next()) { Ref<WebRTCDataChannel> ch = C->get(); switch (ch->get_ready_state()) { case WebRTCDataChannel::STATE_CONNECTING: @@ -130,7 +130,7 @@ void WebRTCMultiplayer::poll() { emit_signal("peer_connected", TARGET_PEER_SERVER); emit_signal("connection_succeeded"); // Notify of all previously connected peers - for (Map<int, Ref<ConnectedPeer> >::Element *F = peer_map.front(); F; F = F->next()) { + for (Map<int, Ref<ConnectedPeer>>::Element *F = peer_map.front(); F; F = F->next()) { if (F->key() != 1 && F->get()->connected) emit_signal("peer_connected", F->key()); } @@ -143,11 +143,11 @@ void WebRTCMultiplayer::poll() { } void WebRTCMultiplayer::_find_next_peer() { - Map<int, Ref<ConnectedPeer> >::Element *E = peer_map.find(next_packet_peer); + Map<int, Ref<ConnectedPeer>>::Element *E = peer_map.find(next_packet_peer); if (E) E = E->next(); // After last. while (E) { - for (List<Ref<WebRTCDataChannel> >::Element *F = E->get()->channels.front(); F; F = F->next()) { + for (List<Ref<WebRTCDataChannel>>::Element *F = E->get()->channels.front(); F; F = F->next()) { if (F->get()->get_available_packet_count()) { next_packet_peer = E->key(); return; @@ -158,7 +158,7 @@ void WebRTCMultiplayer::_find_next_peer() { E = peer_map.front(); // Before last while (E) { - for (List<Ref<WebRTCDataChannel> >::Element *F = E->get()->channels.front(); F; F = F->next()) { + for (List<Ref<WebRTCDataChannel>>::Element *F = E->get()->channels.front(); F; F = F->next()) { if (F->get()->get_available_packet_count()) { next_packet_peer = E->key(); return; @@ -204,7 +204,7 @@ int WebRTCMultiplayer::get_unique_id() const { void WebRTCMultiplayer::_peer_to_dict(Ref<ConnectedPeer> p_connected_peer, Dictionary &r_dict) { Array channels; - for (List<Ref<WebRTCDataChannel> >::Element *F = p_connected_peer->channels.front(); F; F = F->next()) { + for (List<Ref<WebRTCDataChannel>>::Element *F = p_connected_peer->channels.front(); F; F = F->next()) { channels.push_back(F->get()); } r_dict["connection"] = p_connected_peer->connection; @@ -225,7 +225,7 @@ Dictionary WebRTCMultiplayer::get_peer(int p_peer_id) { Dictionary WebRTCMultiplayer::get_peers() { Dictionary out; - for (Map<int, Ref<ConnectedPeer> >::Element *E = peer_map.front(); E; E = E->next()) { + for (Map<int, Ref<ConnectedPeer>>::Element *E = peer_map.front(); E; E = E->next()) { Dictionary d; _peer_to_dict(E->get(), d); out[E->key()] = d; @@ -288,7 +288,7 @@ Error WebRTCMultiplayer::get_packet(const uint8_t **r_buffer, int &r_buffer_size _find_next_peer(); ERR_FAIL_V(ERR_UNAVAILABLE); } - for (List<Ref<WebRTCDataChannel> >::Element *E = peer_map[next_packet_peer]->channels.front(); E; E = E->next()) { + for (List<Ref<WebRTCDataChannel>>::Element *E = peer_map[next_packet_peer]->channels.front(); E; E = E->next()) { if (E->get()->get_available_packet_count()) { Error err = E->get()->get_packet(r_buffer, r_buffer_size); _find_next_peer(); @@ -316,7 +316,7 @@ Error WebRTCMultiplayer::put_packet(const uint8_t *p_buffer, int p_buffer_size) break; } - Map<int, Ref<ConnectedPeer> >::Element *E = NULL; + Map<int, Ref<ConnectedPeer>>::Element *E = NULL; if (target_peer > 0) { @@ -330,7 +330,7 @@ Error WebRTCMultiplayer::put_packet(const uint8_t *p_buffer, int p_buffer_size) } else { int exclude = -target_peer; - for (Map<int, Ref<ConnectedPeer> >::Element *F = peer_map.front(); F; F = F->next()) { + for (Map<int, Ref<ConnectedPeer>>::Element *F = peer_map.front(); F; F = F->next()) { // Exclude packet. If target_peer == 0 then don't exclude any packets if (target_peer != 0 && F->key() == exclude) @@ -347,8 +347,8 @@ int WebRTCMultiplayer::get_available_packet_count() const { if (next_packet_peer == 0) return 0; // To be sure next call to get_packet works if size > 0 . int size = 0; - for (Map<int, Ref<ConnectedPeer> >::Element *E = peer_map.front(); E; E = E->next()) { - for (List<Ref<WebRTCDataChannel> >::Element *F = E->get()->channels.front(); F; F = F->next()) { + for (Map<int, Ref<ConnectedPeer>>::Element *E = peer_map.front(); E; E = E->next()) { + for (List<Ref<WebRTCDataChannel>>::Element *F = E->get()->channels.front(); F; F = F->next()) { size += F->get()->get_available_packet_count(); } } diff --git a/modules/webrtc/webrtc_multiplayer.h b/modules/webrtc/webrtc_multiplayer.h index 66a3cd0ff5..0e1335b8a8 100644 --- a/modules/webrtc/webrtc_multiplayer.h +++ b/modules/webrtc/webrtc_multiplayer.h @@ -53,7 +53,7 @@ private: public: Ref<WebRTCPeerConnection> connection; - List<Ref<WebRTCDataChannel> > channels; + List<Ref<WebRTCDataChannel>> channels; bool connected; ConnectedPeer() { @@ -72,7 +72,7 @@ private: int next_packet_peer; bool server_compat; - Map<int, Ref<ConnectedPeer> > peer_map; + Map<int, Ref<ConnectedPeer>> peer_map; void _peer_to_dict(Ref<ConnectedPeer> p_connected_peer, Dictionary &r_dict); void _find_next_peer(); diff --git a/modules/websocket/emws_client.cpp b/modules/websocket/emws_client.cpp index e5680ce2e9..bbe4d6dc5b 100644 --- a/modules/websocket/emws_client.cpp +++ b/modules/websocket/emws_client.cpp @@ -181,7 +181,7 @@ Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, if (peer_sock == -1) return FAILED; - static_cast<Ref<EMWSPeer> >(_peer)->set_sock(peer_sock, _in_buf_size, _in_pkt_size); + static_cast<Ref<EMWSPeer>>(_peer)->set_sock(peer_sock, _in_buf_size, _in_pkt_size); return OK; }; diff --git a/modules/websocket/websocket_multiplayer_peer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp index 5c01d44ede..9eb1445b35 100644 --- a/modules/websocket/websocket_multiplayer_peer.cpp +++ b/modules/websocket/websocket_multiplayer_peer.cpp @@ -209,7 +209,7 @@ void WebSocketMultiplayerPeer::_send_add(int32_t p_peer_id) { // Then send the server peer (which will trigger connection_succeded in client) _send_sys(get_peer(p_peer_id), SYS_ADD, 1); - for (Map<int, Ref<WebSocketPeer> >::Element *E = _peer_map.front(); E; E = E->next()) { + for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) { int32_t id = E->key(); if (p_peer_id == id) continue; // Skip the newwly added peer (already confirmed) @@ -222,7 +222,7 @@ void WebSocketMultiplayerPeer::_send_add(int32_t p_peer_id) { } void WebSocketMultiplayerPeer::_send_del(int32_t p_peer_id) { - for (Map<int, Ref<WebSocketPeer> >::Element *E = _peer_map.front(); E; E = E->next()) { + for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) { int32_t id = E->key(); if (p_peer_id != id) _send_sys(get_peer(id), SYS_DEL, p_peer_id); @@ -247,7 +247,7 @@ Error WebSocketMultiplayerPeer::_server_relay(int32_t p_from, int32_t p_to, cons } else if (p_to == 0) { - for (Map<int, Ref<WebSocketPeer> >::Element *E = _peer_map.front(); E; E = E->next()) { + for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) { if (E->key() != p_from) E->get()->put_packet(p_buffer, p_buffer_size); } @@ -255,7 +255,7 @@ Error WebSocketMultiplayerPeer::_server_relay(int32_t p_from, int32_t p_to, cons } else if (p_to < 0) { - for (Map<int, Ref<WebSocketPeer> >::Element *E = _peer_map.front(); E; E = E->next()) { + for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) { if (E->key() != p_from && E->key() != -p_to) E->get()->put_packet(p_buffer, p_buffer_size); } diff --git a/modules/websocket/websocket_multiplayer_peer.h b/modules/websocket/websocket_multiplayer_peer.h index 579972ada2..c6669c730c 100644 --- a/modules/websocket/websocket_multiplayer_peer.h +++ b/modules/websocket/websocket_multiplayer_peer.h @@ -63,7 +63,7 @@ protected: }; List<Packet> _incoming_packets; - Map<int, Ref<WebSocketPeer> > _peer_map; + Map<int, Ref<WebSocketPeer>> _peer_map; Packet _current_packet; bool _is_multiplayer; diff --git a/modules/websocket/wsl_client.cpp b/modules/websocket/wsl_client.cpp index 088f266f18..bada750ec2 100644 --- a/modules/websocket/wsl_client.cpp +++ b/modules/websocket/wsl_client.cpp @@ -253,7 +253,7 @@ void WSLClient::poll() { } _connection = ssl; } else { - ssl = static_cast<Ref<StreamPeerSSL> >(_connection); + ssl = static_cast<Ref<StreamPeerSSL>>(_connection); ERR_FAIL_COND(ssl.is_null()); // Bug? ssl->poll(); } diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp index 4db650a0c1..b66cdf3ea2 100644 --- a/modules/websocket/wsl_server.cpp +++ b/modules/websocket/wsl_server.cpp @@ -103,7 +103,7 @@ Error WSLServer::PendingPeer::do_handshake(const Vector<String> p_protocols) { if (OS::get_singleton()->get_ticks_msec() - time > WSL_SERVER_TIMEOUT) return ERR_TIMEOUT; if (use_ssl) { - Ref<StreamPeerSSL> ssl = static_cast<Ref<StreamPeerSSL> >(connection); + Ref<StreamPeerSSL> ssl = static_cast<Ref<StreamPeerSSL>>(connection); if (ssl.is_null()) return FAILED; ssl->poll(); @@ -171,7 +171,7 @@ Error WSLServer::listen(int p_port, const Vector<String> p_protocols, bool gd_mp void WSLServer::poll() { List<int> remove_ids; - for (Map<int, Ref<WebSocketPeer> >::Element *E = _peer_map.front(); E; E = E->next()) { + for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) { Ref<WSLPeer> peer = (WSLPeer *)E->get().ptr(); peer->poll(); if (!peer->is_connected_to_host()) { @@ -184,8 +184,8 @@ void WSLServer::poll() { } remove_ids.clear(); - List<Ref<PendingPeer> > remove_peers; - for (List<Ref<PendingPeer> >::Element *E = _pending.front(); E; E = E->next()) { + List<Ref<PendingPeer>> remove_peers; + for (List<Ref<PendingPeer>>::Element *E = _pending.front(); E; E = E->next()) { Ref<PendingPeer> ppeer = E->get(); Error err = ppeer->do_handshake(_protocols); if (err == ERR_BUSY) { @@ -212,7 +212,7 @@ void WSLServer::poll() { remove_peers.push_back(ppeer); _on_connect(id, ppeer->protocol); } - for (List<Ref<PendingPeer> >::Element *E = remove_peers.front(); E; E = E->next()) { + for (List<Ref<PendingPeer>>::Element *E = remove_peers.front(); E; E = E->next()) { _pending.erase(E->get()); } remove_peers.clear(); @@ -251,7 +251,7 @@ int WSLServer::get_max_packet_size() const { void WSLServer::stop() { _server->stop(); - for (Map<int, Ref<WebSocketPeer> >::Element *E = _peer_map.front(); E; E = E->next()) { + for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) { Ref<WSLPeer> peer = (WSLPeer *)E->get().ptr(); peer->close_now(); } diff --git a/modules/websocket/wsl_server.h b/modules/websocket/wsl_server.h index 649d1adee6..2e893d6727 100644 --- a/modules/websocket/wsl_server.h +++ b/modules/websocket/wsl_server.h @@ -76,7 +76,7 @@ private: int _out_buf_size; int _out_pkt_size; - List<Ref<PendingPeer> > _pending; + List<Ref<PendingPeer>> _pending; Ref<TCP_Server> _server; Vector<String> _protocols; diff --git a/platform/android/api/java_class_wrapper.h b/platform/android/api/java_class_wrapper.h index 48b581958b..d7322deb81 100644 --- a/platform/android/api/java_class_wrapper.h +++ b/platform/android/api/java_class_wrapper.h @@ -163,7 +163,7 @@ class JavaClass : public Reference { bool _call_method(JavaObject *p_instance, const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error, Variant &ret); friend class JavaClassWrapper; - Map<StringName, List<MethodInfo> > methods; + Map<StringName, List<MethodInfo>> methods; jclass _class; #endif @@ -198,7 +198,7 @@ class JavaClassWrapper : public Object { GDCLASS(JavaClassWrapper, Object); #ifdef ANDROID_ENABLED - Map<String, Ref<JavaClass> > class_cache; + Map<String, Ref<JavaClass>> class_cache; friend class JavaClass; jclass activityClass; jmethodID findClass; diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle index 5e37f538e9..1a3bb77670 100644 --- a/platform/android/java/app/build.gradle +++ b/platform/android/java/app/build.gradle @@ -71,6 +71,7 @@ android { packagingOptions { exclude 'META-INF/LICENSE' exclude 'META-INF/NOTICE' + doNotStrip '**/*.so' } // Both signing and zip-aligning will be done at export time diff --git a/platform/android/java/build.gradle b/platform/android/java/build.gradle index 976a5bda99..865b61956c 100644 --- a/platform/android/java/build.gradle +++ b/platform/android/java/build.gradle @@ -25,7 +25,7 @@ ext { sconsExt = org.gradle.internal.os.OperatingSystem.current().isWindows() ? ".bat" : "" supportedAbis = ["armv7", "arm64v8", "x86", "x86_64"] - supportedTargets = ['release': "release", 'debug': "release_debug"] + supportedTargets = ["release", "debug"] // Used by gradle to specify which architecture to build for by default when running `./gradlew build`. // This command is usually used by Android Studio. @@ -136,14 +136,14 @@ task zipCustomBuild(type: Zip) { */ task generateGodotTemplates(type: GradleBuild) { // We exclude these gradle tasks so we can run the scons command manually. - for (String buildType : supportedTargets.keySet()) { + for (String buildType : supportedTargets) { startParameter.excludedTaskNames += ":lib:" + getSconsTaskName(buildType) } tasks = ["copyGodotPaymentPluginToAppModule"] // Only build the apks and aar files for which we have native shared libraries. - for (String target : supportedTargets.keySet()) { + for (String target : supportedTargets) { File targetLibs = new File("lib/libs/" + target) if (targetLibs != null && targetLibs.isDirectory() diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle index ca8aaf8af0..062f91e08e 100644 --- a/platform/android/java/lib/build.gradle +++ b/platform/android/java/lib/build.gradle @@ -26,6 +26,7 @@ android { packagingOptions { exclude 'META-INF/LICENSE' exclude 'META-INF/NOTICE' + doNotStrip '**/*.so' } sourceSets { @@ -56,7 +57,7 @@ android { // files is only setup for editing support. gradle.startParameter.excludedTaskNames += taskPrefix + "externalNativeBuild" + buildType - def releaseTarget = supportedTargets[buildType.toLowerCase()] + def releaseTarget = buildType.toLowerCase() if (releaseTarget == null || releaseTarget == "") { throw new GradleException("Invalid build type: " + buildType) } diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java index 7db4aa6597..4e605f9950 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java @@ -95,7 +95,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Locale; import org.godotengine.godot.input.GodotEditText; -import org.godotengine.godot.payments.PaymentsManager; import org.godotengine.godot.plugin.GodotPlugin; import org.godotengine.godot.plugin.GodotPluginRegistry; import org.godotengine.godot.utils.GodotNetUtils; @@ -174,21 +173,17 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe } public ResultCallback result_callback; - private PaymentsManager mPaymentsManager = null; - @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == PaymentsManager.REQUEST_CODE_FOR_PURCHASE) { - mPaymentsManager.processPurchaseResponse(resultCode, data); - } else if (result_callback != null) { + if (result_callback != null) { result_callback.callback(requestCode, resultCode, data); result_callback = null; - }; + } for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) { plugin.onMainActivityResult(requestCode, resultCode, data); } - }; + } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { @@ -445,8 +440,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe result_callback = null; - mPaymentsManager = PaymentsManager.createManager(this).initService(); - godot_initialized = true; } @@ -603,7 +596,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe @Override protected void onDestroy() { - if (mPaymentsManager != null) mPaymentsManager.destroy(); for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) { plugin.onMainDestroy(); } @@ -938,10 +930,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe return true; } - public PaymentsManager getPaymentsManager() { - return mPaymentsManager; - } - public boolean requestPermission(String p_name) { return PermissionsUtil.requestPermission(p_name, this); } diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java index 8d9b5461a1..18f2d57661 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java @@ -110,8 +110,13 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene @Override public void run() { for (int i = 0; i < count; ++i) { - GodotLib.key(0, 0, newChars[i], true); - GodotLib.key(0, 0, newChars[i], false); + int key = newChars[i]; + if (key == '\n') { + // Return keys are handled through action events + continue; + } + GodotLib.key(0, 0, key, true); + GodotLib.key(0, 0, key, false); } } }); @@ -134,8 +139,13 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene }); } - if (pActionID == EditorInfo.IME_ACTION_DONE) { + if (pActionID == EditorInfo.IME_NULL) { + // Enter key has been pressed + GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, true); + GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, false); + this.mView.requestFocus(); + return true; } return false; } diff --git a/platform/android/java/lib/aidl/com/android/vending/billing/IInAppBillingService.aidl b/platform/android/java/plugins/godotpayment/src/main/aidl/com/android/vending/billing/IInAppBillingService.aidl index 0f2bcae338..0f2bcae338 100644 --- a/platform/android/java/lib/aidl/com/android/vending/billing/IInAppBillingService.aidl +++ b/platform/android/java/plugins/godotpayment/src/main/aidl/com/android/vending/billing/IInAppBillingService.aidl diff --git a/platform/android/java/lib/src/org/godotengine/godot/payments/ConsumeTask.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ConsumeTask.java index 95cc48f536..c15bc232ce 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/ConsumeTask.java +++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ConsumeTask.java @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -package org.godotengine.godot.payments; +package org.godotengine.godot.plugin.payment; import android.content.Context; import android.os.AsyncTask; diff --git a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/GodotPayment.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/GodotPayment.java index 4a6b611c4d..c7d0a5de65 100644 --- a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/GodotPayment.java +++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/GodotPayment.java @@ -30,6 +30,7 @@ package org.godotengine.godot.plugin.payment; +import android.content.Intent; import android.support.annotation.NonNull; import android.util.Log; import java.util.ArrayList; @@ -38,28 +39,40 @@ import java.util.List; import org.godotengine.godot.Dictionary; import org.godotengine.godot.Godot; import org.godotengine.godot.GodotLib; -import org.godotengine.godot.payments.GodotPaymentInterface; -import org.godotengine.godot.payments.PaymentsManager; import org.godotengine.godot.plugin.GodotPlugin; import org.json.JSONException; import org.json.JSONObject; -public class GodotPayment extends GodotPlugin implements GodotPaymentInterface { +public class GodotPayment extends GodotPlugin { private Integer purchaseCallbackId = 0; private String accessToken; private String purchaseValidationUrlPrefix; private String transactionId; - private PaymentsManager mPaymentManager; - private Dictionary mSkuDetails = new Dictionary(); + private final PaymentsManager mPaymentManager; + private final Dictionary mSkuDetails = new Dictionary(); public GodotPayment(Godot godot) { super(godot); - mPaymentManager = godot.getPaymentsManager(); - mPaymentManager.setBaseSingleton(this); + mPaymentManager = new PaymentsManager(godot, this); + mPaymentManager.initService(); } @Override + public void onMainActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == PaymentsManager.REQUEST_CODE_FOR_PURCHASE) { + mPaymentManager.processPurchaseResponse(resultCode, data); + } + } + + @Override + public void onMainDestroy() { + super.onMainDestroy(); + if (mPaymentManager != null) { + mPaymentManager.destroy(); + } + } + public void purchase(final String sku, final String transactionId) { runOnUiThread(new Runnable() { @Override @@ -69,7 +82,6 @@ public class GodotPayment extends GodotPlugin implements GodotPaymentInterface { }); } - @Override public void consumeUnconsumedPurchases() { runOnUiThread(new Runnable() { @Override @@ -81,89 +93,72 @@ public class GodotPayment extends GodotPlugin implements GodotPaymentInterface { private String signature; - @Override public String getSignature() { return this.signature; } - @Override public void callbackSuccess(String ticket, String signature, String sku) { GodotLib.calldeferred(purchaseCallbackId, "purchase_success", new Object[] { ticket, signature, sku }); } - @Override public void callbackSuccessProductMassConsumed(String ticket, String signature, String sku) { Log.d(this.getClass().getName(), "callbackSuccessProductMassConsumed > " + ticket + "," + signature + "," + sku); GodotLib.calldeferred(purchaseCallbackId, "consume_success", new Object[] { ticket, signature, sku }); } - @Override public void callbackSuccessNoUnconsumedPurchases() { GodotLib.calldeferred(purchaseCallbackId, "consume_not_required", new Object[] {}); } - @Override public void callbackFailConsume(String message) { GodotLib.calldeferred(purchaseCallbackId, "consume_fail", new Object[] { message }); } - @Override public void callbackFail(String message) { GodotLib.calldeferred(purchaseCallbackId, "purchase_fail", new Object[] { message }); } - @Override public void callbackCancel() { GodotLib.calldeferred(purchaseCallbackId, "purchase_cancel", new Object[] {}); } - @Override public void callbackAlreadyOwned(String sku) { GodotLib.calldeferred(purchaseCallbackId, "purchase_owned", new Object[] { sku }); } - @Override public int getPurchaseCallbackId() { return purchaseCallbackId; } - @Override public void setPurchaseCallbackId(int purchaseCallbackId) { this.purchaseCallbackId = purchaseCallbackId; } - @Override public String getPurchaseValidationUrlPrefix() { return this.purchaseValidationUrlPrefix; } - @Override public void setPurchaseValidationUrlPrefix(String url) { this.purchaseValidationUrlPrefix = url; } - @Override public String getAccessToken() { return accessToken; } - @Override public void setAccessToken(String accessToken) { this.accessToken = accessToken; } - @Override public void setTransactionId(String transactionId) { this.transactionId = transactionId; } - @Override public String getTransactionId() { return this.transactionId; } // request purchased items are not consumed - @Override public void requestPurchased() { runOnUiThread(new Runnable() { @Override @@ -174,41 +169,34 @@ public class GodotPayment extends GodotPlugin implements GodotPaymentInterface { } // callback for requestPurchased() - @Override public void callbackPurchased(String receipt, String signature, String sku) { GodotLib.calldeferred(purchaseCallbackId, "has_purchased", new Object[] { receipt, signature, sku }); } - @Override public void callbackDisconnected() { GodotLib.calldeferred(purchaseCallbackId, "iap_disconnected", new Object[] {}); } - @Override public void callbackConnected() { GodotLib.calldeferred(purchaseCallbackId, "iap_connected", new Object[] {}); } // true if connected, false otherwise - @Override public boolean isConnected() { return mPaymentManager.isConnected(); } // consume item automatically after purchase. default is true. - @Override public void setAutoConsume(boolean autoConsume) { mPaymentManager.setAutoConsume(autoConsume); } // consume a specific item - @Override public void consume(String sku) { mPaymentManager.consume(sku); } // query in app item detail info - @Override public void querySkuDetails(String[] list) { List<String> nKeys = Arrays.asList(list); List<String> cKeys = Arrays.asList(mSkuDetails.get_keys()); @@ -225,7 +213,6 @@ public class GodotPayment extends GodotPlugin implements GodotPaymentInterface { } } - @Override public void addSkuDetail(String itemJson) { JSONObject o = null; try { @@ -244,12 +231,10 @@ public class GodotPayment extends GodotPlugin implements GodotPaymentInterface { } } - @Override public void completeSkuDetail() { GodotLib.calldeferred(purchaseCallbackId, "sku_details_complete", new Object[] { mSkuDetails }); } - @Override public void errorSkuDetail(String errorMessage) { GodotLib.calldeferred(purchaseCallbackId, "sku_details_error", new Object[] { errorMessage }); } @@ -263,6 +248,8 @@ public class GodotPayment extends GodotPlugin implements GodotPaymentInterface { @NonNull @Override public List<String> getPluginMethods() { - return Arrays.asList("purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix", "setTransactionId", "getSignature", "consumeUnconsumedPurchases", "requestPurchased", "setAutoConsume", "consume", "querySkuDetails", "isConnected"); + return Arrays.asList("purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix", + "setTransactionId", "getSignature", "consumeUnconsumedPurchases", "requestPurchased", + "setAutoConsume", "consume", "querySkuDetails", "isConnected"); } } diff --git a/platform/android/java/lib/src/org/godotengine/godot/payments/HandlePurchaseTask.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/HandlePurchaseTask.java index 23d693cc8c..fe5685288b 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/HandlePurchaseTask.java +++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/HandlePurchaseTask.java @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -package org.godotengine.godot.payments; +package org.godotengine.godot.plugin.payment; import android.app.Activity; import android.content.Intent; diff --git a/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsCache.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PaymentsCache.java index 84a7eda6e0..d5919e3d9d 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsCache.java +++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PaymentsCache.java @@ -28,11 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -package org.godotengine.godot.payments; +package org.godotengine.godot.plugin.payment; import android.content.Context; import android.content.SharedPreferences; -import android.util.Log; public class PaymentsCache { diff --git a/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsManager.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PaymentsManager.java index 9bf6650f84..bded1f452f 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsManager.java +++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PaymentsManager.java @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -package org.godotengine.godot.payments; +package org.godotengine.godot.plugin.payment; import android.app.Activity; import android.content.ComponentName; @@ -52,20 +52,13 @@ public class PaymentsManager { public static final int REQUEST_CODE_FOR_PURCHASE = 0x1001; private static boolean auto_consume = true; - private Activity activity; + private final Activity activity; + private final GodotPayment godotPayment; IInAppBillingService mService; - public void setActivity(Activity activity) { - this.activity = activity; - } - - public static PaymentsManager createManager(Activity activity) { - PaymentsManager manager = new PaymentsManager(activity); - return manager; - } - - private PaymentsManager(Activity activity) { + PaymentsManager(Activity activity, GodotPayment godotPayment) { this.activity = activity; + this.godotPayment = godotPayment; } public PaymentsManager initService() { @@ -409,10 +402,4 @@ public class PaymentsManager { })) .start(); } - - private GodotPaymentInterface godotPayment; - - public void setBaseSingleton(GodotPaymentInterface godotPaymentInterface) { - this.godotPayment = godotPaymentInterface; - } } diff --git a/platform/android/java/lib/src/org/godotengine/godot/payments/PurchaseTask.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PurchaseTask.java index 09c9349124..eecd1d2151 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/PurchaseTask.java +++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PurchaseTask.java @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -package org.godotengine.godot.payments; +package org.godotengine.godot.plugin.payment; import android.app.Activity; import android.app.PendingIntent; diff --git a/platform/android/java/lib/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ReleaseAllConsumablesTask.java index a101780511..b7bd638feb 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java +++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ReleaseAllConsumablesTask.java @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -package org.godotengine.godot.payments; +package org.godotengine.godot.plugin.payment; import android.content.Context; import android.os.AsyncTask; diff --git a/platform/android/java/lib/src/org/godotengine/godot/payments/ValidateTask.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ValidateTask.java index 10c314aecf..179cc08ed1 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/ValidateTask.java +++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ValidateTask.java @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -package org.godotengine.godot.payments; +package org.godotengine.godot.plugin.payment; import android.app.Activity; import android.app.ProgressDialog; @@ -42,7 +42,7 @@ import org.json.JSONObject; abstract public class ValidateTask { private Activity context; - private GodotPaymentInterface godotPayments; + private GodotPayment godotPayments; private ProgressDialog dialog; private String mSku; @@ -79,7 +79,7 @@ abstract public class ValidateTask { } } - public ValidateTask(Activity context, GodotPaymentInterface godotPayments) { + public ValidateTask(Activity context, GodotPayment godotPayments) { this.context = context; this.godotPayments = godotPayments; } diff --git a/platform/android/java_class_wrapper.cpp b/platform/android/java_class_wrapper.cpp index 9e9b17fb99..13550c4b11 100644 --- a/platform/android/java_class_wrapper.cpp +++ b/platform/android/java_class_wrapper.cpp @@ -34,7 +34,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error, Variant &ret) { - Map<StringName, List<MethodInfo> >::Element *M = methods.find(p_method); + Map<StringName, List<MethodInfo>>::Element *M = methods.find(p_method); if (!M) return false; diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 7e2b0d948e..8021d6dd07 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -91,7 +91,7 @@ void OS_Android::initialize_core() { FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_RESOURCES); else { #ifdef USE_JAVA_FILE_ACCESS - FileAccess::make_default<FileAccessBufferedFA<FileAccessJAndroid> >(FileAccess::ACCESS_RESOURCES); + FileAccess::make_default<FileAccessBufferedFA<FileAccessJAndroid>>(FileAccess::ACCESS_RESOURCES); #else //FileAccess::make_default<FileAccessBufferedFA<FileAccessAndroid> >(FileAccess::ACCESS_RESOURCES); FileAccess::make_default<FileAccessAndroid>(FileAccess::ACCESS_RESOURCES); diff --git a/platform/iphone/app_delegate.h b/platform/iphone/app_delegate.h index 6b3b7ad5bc..27552d781a 100644 --- a/platform/iphone/app_delegate.h +++ b/platform/iphone/app_delegate.h @@ -36,9 +36,11 @@ #import <CoreMotion/CoreMotion.h> -#if defined(OPENGL_ENABLED) -@interface AppDelegate : NSObject <UIApplicationDelegate, GLViewDelegate> { -#endif +// FIXME: Add support for both GLES2 and Vulkan when GLES2 is implemented again, +// so it can't be done with compilation time branching. +//#if defined(OPENGL_ENABLED) +//@interface AppDelegate : NSObject <UIApplicationDelegate, GLViewDelegate> { +//#endif #if defined(VULKAN_ENABLED) @interface AppDelegate : NSObject <UIApplicationDelegate> { #endif diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm index acc3e5d4e0..0ac8bb7a56 100644 --- a/platform/iphone/app_delegate.mm +++ b/platform/iphone/app_delegate.mm @@ -648,7 +648,6 @@ static int frame_count = 0; view_controller = [[ViewController alloc] init]; view_controller.view = glView; - _set_keep_screen_on(bool(GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true)) ? YES : NO); glView.useCADisplayLink = bool(GLOBAL_DEF("display.iOS/use_cadisplaylink", true)) ? YES : NO; diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp index 7cef2351e3..08f3c3f91f 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -410,7 +410,7 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_ } String EditorExportPlatformIOS::_get_additional_plist_content() { - Vector<Ref<EditorExportPlugin> > export_plugins = EditorExport::get_singleton()->get_export_plugins(); + Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins(); String result; for (int i = 0; i < export_plugins.size(); ++i) { result += export_plugins[i]->get_ios_plist_content(); @@ -419,7 +419,7 @@ String EditorExportPlatformIOS::_get_additional_plist_content() { } String EditorExportPlatformIOS::_get_linker_flags() { - Vector<Ref<EditorExportPlugin> > export_plugins = EditorExport::get_singleton()->get_export_plugins(); + Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins(); String result; for (int i = 0; i < export_plugins.size(); ++i) { String flags = export_plugins[i]->get_ios_linker_flags(); @@ -434,7 +434,7 @@ String EditorExportPlatformIOS::_get_linker_flags() { } String EditorExportPlatformIOS::_get_cpp_code() { - Vector<Ref<EditorExportPlugin> > export_plugins = EditorExport::get_singleton()->get_export_plugins(); + Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins(); String result; for (int i = 0; i < export_plugins.size(); ++i) { result += export_plugins[i]->get_ios_cpp_code(); @@ -776,7 +776,7 @@ struct ExportLibsData { }; void EditorExportPlatformIOS::_add_assets_to_project(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_project_data, const Vector<IOSExportAsset> &p_additional_assets) { - Vector<Ref<EditorExportPlugin> > export_plugins = EditorExport::get_singleton()->get_export_plugins(); + Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins(); Vector<String> frameworks; for (int i = 0; i < export_plugins.size(); ++i) { Vector<String> plugin_frameworks = export_plugins[i]->get_ios_frameworks(); @@ -920,7 +920,7 @@ Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir } Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir, const Vector<SharedObject> &p_libraries, Vector<IOSExportAsset> &r_exported_assets) { - 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++) { Vector<String> frameworks = export_plugins[i]->get_ios_frameworks(); Error err = _export_additional_assets(p_out_dir, frameworks, true, r_exported_assets); diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub index 85a633442e..d3cd8f76b7 100644 --- a/platform/javascript/SCsub +++ b/platform/javascript/SCsub @@ -10,8 +10,11 @@ javascript_files = [ 'os_javascript.cpp', ] -build = env.add_program(['#bin/godot${PROGSUFFIX}.js', '#bin/godot${PROGSUFFIX}.wasm'], javascript_files); -js, wasm = build +build_targets = ['#bin/godot${PROGSUFFIX}.js', '#bin/godot${PROGSUFFIX}.wasm'] +if env['threads_enabled']: + build_targets.append('#bin/godot${PROGSUFFIX}.worker.js') + +build = env.add_program(build_targets, javascript_files) js_libraries = [ 'http_request.js', @@ -27,18 +30,38 @@ for module in js_modules: env.Append(LINKFLAGS=['--pre-js', env.File(module).path]) env.Depends(build, js_modules) -wrapper_start = env.File('pre.js') -wrapper_end = env.File('engine.js') -js_wrapped = env.Textfile('#bin/godot', [wrapper_start, js, wrapper_end], TEXTFILESUFFIX='${PROGSUFFIX}.wrapped.js') +engine = [ + 'engine/preloader.js', + 'engine/loader.js', + 'engine/utils.js', + 'engine/engine.js', +] +externs = [ + env.File('#platform/javascript/engine/externs.js') +] +js_engine = env.CreateEngineFile('#bin/godot${PROGSUFFIX}.engine.js', engine, externs) +env.Depends(js_engine, externs) + +wrap_list = [ + build[0], + js_engine, +] +js_wrapped = env.Textfile('#bin/godot', [env.File(f) for f in wrap_list], TEXTFILESUFFIX='${PROGSUFFIX}.wrapped.js') zip_dir = env.Dir('#bin/.javascript_zip') -zip_files = env.InstallAs([ +out_files = [ zip_dir.File('godot.js'), zip_dir.File('godot.wasm'), zip_dir.File('godot.html') -], [ +] +in_files = [ js_wrapped, - wasm, + build[1], '#misc/dist/html/full-size.html' -]) +] +if env['threads_enabled']: + in_files.append(build[2]) + out_files.append(zip_dir.File('godot.worker.js')) + +zip_files = env.InstallAs(out_files, in_files) env.Zip('#bin/godot', zip_files, ZIPROOT=zip_dir, ZIPSUFFIX='${PROGSUFFIX}${ZIPSUFFIX}', ZIPCOMSTR='Archving $SOURCES as $TARGET') diff --git a/platform/javascript/audio_driver_javascript.cpp b/platform/javascript/audio_driver_javascript.cpp index f1bc7c4382..d63c6a40a5 100644 --- a/platform/javascript/audio_driver_javascript.cpp +++ b/platform/javascript/audio_driver_javascript.cpp @@ -69,31 +69,37 @@ void AudioDriverJavaScript::process_capture(float sample) { Error AudioDriverJavaScript::init() { /* clang-format off */ - EM_ASM({ - _audioDriver_audioContext = new (window.AudioContext || window.webkitAudioContext); - _audioDriver_audioInput = null; - _audioDriver_inputStream = null; - _audioDriver_scriptNode = null; + _driver_id = EM_ASM_INT({ + return Module.IDHandler.add({ + 'context': new (window.AudioContext || window.webkitAudioContext), + 'input': null, + 'stream': null, + 'script': null + }); }); /* clang-format on */ int channel_count = get_total_channels_by_speaker_mode(get_speaker_mode()); /* clang-format off */ buffer_length = EM_ASM_INT({ - var CHANNEL_COUNT = $0; + var ref = Module.IDHandler.get($0); + var ctx = ref['context']; + var CHANNEL_COUNT = $1; - var channelCount = _audioDriver_audioContext.destination.channelCount; + var channelCount = ctx.destination.channelCount; + var script = null; try { // Try letting the browser recommend a buffer length. - _audioDriver_scriptNode = _audioDriver_audioContext.createScriptProcessor(0, 2, channelCount); + script = ctx.createScriptProcessor(0, 2, channelCount); } catch (e) { // ...otherwise, default to 4096. - _audioDriver_scriptNode = _audioDriver_audioContext.createScriptProcessor(4096, 2, channelCount); + script = ctx.createScriptProcessor(4096, 2, channelCount); } - _audioDriver_scriptNode.connect(_audioDriver_audioContext.destination); + script.connect(ctx.destination); + ref['script'] = script; - return _audioDriver_scriptNode.bufferSize; - }, channel_count); + return script.bufferSize; + }, _driver_id, channel_count); /* clang-format on */ if (!buffer_length) { return FAILED; @@ -112,11 +118,12 @@ void AudioDriverJavaScript::start() { /* clang-format off */ EM_ASM({ - var INTERNAL_BUFFER_PTR = $0; + const ref = Module.IDHandler.get($0); + var INTERNAL_BUFFER_PTR = $1; var audioDriverMixFunction = cwrap('audio_driver_js_mix'); var audioDriverProcessCapture = cwrap('audio_driver_process_capture', null, ['number']); - _audioDriver_scriptNode.onaudioprocess = function(audioProcessingEvent) { + ref['script'].onaudioprocess = function(audioProcessingEvent) { audioDriverMixFunction(); var input = audioProcessingEvent.inputBuffer; @@ -133,7 +140,7 @@ void AudioDriverJavaScript::start() { } } - if (_audioDriver_audioInput) { + if (ref['input']) { var inputDataL = input.getChannelData(0); var inputDataR = input.getChannelData(1); for (var i = 0; i < inputDataL.length; i++) { @@ -142,34 +149,37 @@ void AudioDriverJavaScript::start() { } } }; - }, internal_buffer); + }, _driver_id, internal_buffer); /* clang-format on */ } void AudioDriverJavaScript::resume() { /* clang-format off */ EM_ASM({ - if (_audioDriver_audioContext.resume) - _audioDriver_audioContext.resume(); - }); + const ref = Module.IDHandler.get($0); + if (ref && ref['context'] && ref['context'].resume) + ref['context'].resume(); + }, _driver_id); /* clang-format on */ } int AudioDriverJavaScript::get_mix_rate() const { /* clang-format off */ - return EM_ASM_INT_V({ - return _audioDriver_audioContext.sampleRate; - }); + return EM_ASM_INT({ + const ref = Module.IDHandler.get($0); + return ref && ref['context'] ? ref['context'].sampleRate : 0; + }, _driver_id); /* clang-format on */ } AudioDriver::SpeakerMode AudioDriverJavaScript::get_speaker_mode() const { /* clang-format off */ - return get_speaker_mode_by_total_channels(EM_ASM_INT_V({ - return _audioDriver_audioContext.destination.channelCount; - })); + return get_speaker_mode_by_total_channels(EM_ASM_INT({ + const ref = Module.IDHandler.get($0); + return ref && ref['context'] ? ref['context'].destination.channelCount : 0; + }, _driver_id)); /* clang-format on */ } @@ -184,16 +194,15 @@ void AudioDriverJavaScript::finish() { /* clang-format off */ EM_ASM({ - _audioDriver_audioContext = null; - _audioDriver_audioInput = null; - _audioDriver_scriptNode = null; - }); + Module.IDHandler.remove($0); + }, _driver_id); /* clang-format on */ if (internal_buffer) { memdelete_arr(internal_buffer); internal_buffer = NULL; } + _driver_id = 0; } Error AudioDriverJavaScript::capture_start() { @@ -203,9 +212,10 @@ Error AudioDriverJavaScript::capture_start() { /* clang-format off */ EM_ASM({ function gotMediaInput(stream) { - _audioDriver_inputStream = stream; - _audioDriver_audioInput = _audioDriver_audioContext.createMediaStreamSource(stream); - _audioDriver_audioInput.connect(_audioDriver_scriptNode); + var ref = Module.IDHandler.get($0); + ref['stream'] = stream; + ref['input'] = ref['context'].createMediaStreamSource(stream); + ref['input'].connect(ref['script']); } function gotMediaInputError(e) { @@ -219,7 +229,7 @@ Error AudioDriverJavaScript::capture_start() { navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia; navigator.getUserMedia({"audio": true}, gotMediaInput, gotMediaInputError); } - }); + }, _driver_id); /* clang-format on */ return OK; @@ -229,20 +239,21 @@ Error AudioDriverJavaScript::capture_stop() { /* clang-format off */ EM_ASM({ - if (_audioDriver_inputStream) { - const tracks = _audioDriver_inputStream.getTracks(); + var ref = Module.IDHandler.get($0); + if (ref['stream']) { + const tracks = ref['stream'].getTracks(); for (var i = 0; i < tracks.length; i++) { tracks[i].stop(); } - _audioDriver_inputStream = null; + ref['stream'] = null; } - if (_audioDriver_audioInput) { - _audioDriver_audioInput.disconnect(); - _audioDriver_audioInput = null; + if (ref['input']) { + ref['input'].disconnect(); + ref['input'] = null; } - }); + }, _driver_id); /* clang-format on */ input_buffer.clear(); @@ -252,7 +263,9 @@ Error AudioDriverJavaScript::capture_stop() { AudioDriverJavaScript::AudioDriverJavaScript() { + _driver_id = 0; internal_buffer = NULL; + buffer_length = 0; singleton = this; } diff --git a/platform/javascript/audio_driver_javascript.h b/platform/javascript/audio_driver_javascript.h index 2bb97ba192..f6f2dacd4e 100644 --- a/platform/javascript/audio_driver_javascript.h +++ b/platform/javascript/audio_driver_javascript.h @@ -37,6 +37,7 @@ class AudioDriverJavaScript : public AudioDriver { float *internal_buffer; + int _driver_id; int buffer_length; public: diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py index 1766833364..fb02752aa7 100644 --- a/platform/javascript/detect.py +++ b/platform/javascript/detect.py @@ -1,5 +1,6 @@ import os +from emscripten_helpers import parse_config, run_closure_compiler, create_engine_file def is_active(): return True @@ -18,6 +19,8 @@ def get_opts(): return [ # eval() can be a security concern, so it can be disabled. BoolVariable('javascript_eval', 'Enable JavaScript eval interface', True), + BoolVariable('threads_enabled', 'Enable WebAssembly Threads support (limited browser support)', False), + BoolVariable('use_closure_compiler', 'Use closure compiler to minimize Javascript code', False), ] @@ -37,7 +40,7 @@ def configure(env): ## Build type - if env['target'] != 'debug': + if env['target'] == 'release': # Use -Os to prioritize optimizing for reduced file size. This is # particularly valuable for the web platform because it directly # decreases download time. @@ -46,38 +49,55 @@ def configure(env): # run-time performance. env.Append(CCFLAGS=['-Os']) env.Append(LINKFLAGS=['-Os']) - if env['target'] == 'release_debug': - env.Append(CPPDEFINES=['DEBUG_ENABLED']) - # Retain function names for backtraces at the cost of file size. - env.Append(LINKFLAGS=['--profiling-funcs']) - else: + elif env['target'] == 'release_debug': + env.Append(CCFLAGS=['-Os']) + env.Append(LINKFLAGS=['-Os']) + env.Append(CPPDEFINES=['DEBUG_ENABLED']) + # Retain function names for backtraces at the cost of file size. + env.Append(LINKFLAGS=['--profiling-funcs']) + else: # 'debug' env.Append(CPPDEFINES=['DEBUG_ENABLED']) env.Append(CCFLAGS=['-O1', '-g']) env.Append(LINKFLAGS=['-O1', '-g']) env.Append(LINKFLAGS=['-s', 'ASSERTIONS=1']) - ## Compiler configuration + if env['tools']: + if not env['threads_enabled']: + raise RuntimeError("Threads must be enabled to build the editor. Please add the 'threads_enabled=yes' option") + # Tools need more memory. Initial stack memory in bytes. See `src/settings.js` in emscripten repository (will be renamed to INITIAL_MEMORY). + env.Append(LINKFLAGS=['-s', 'TOTAL_MEMORY=33554432']) + else: + # Disable exceptions and rtti on non-tools (template) builds + # These flags help keep the file size down. + env.Append(CCFLAGS=['-fno-exceptions', '-fno-rtti']) + # Don't use dynamic_cast, necessary with no-rtti. + env.Append(CPPDEFINES=['NO_SAFE_CAST']) + ## Copy env variables. env['ENV'] = os.environ - em_config_file = os.getenv('EM_CONFIG') or os.path.expanduser('~/.emscripten') - if not os.path.exists(em_config_file): - raise RuntimeError("Emscripten configuration file '%s' does not exist" % em_config_file) - with open(em_config_file) as f: - em_config = {} - try: - # Emscripten configuration file is a Python file with simple assignments. - exec(f.read(), em_config) - except StandardError as e: - raise RuntimeError("Emscripten configuration file '%s' is invalid:\n%s" % (em_config_file, e)) - if 'BINARYEN_ROOT' in em_config and os.path.isdir(os.path.join(em_config.get('BINARYEN_ROOT'), 'emscripten')): - # New style, emscripten path as a subfolder of BINARYEN_ROOT - env.PrependENVPath('PATH', os.path.join(em_config.get('BINARYEN_ROOT'), 'emscripten')) - elif 'EMSCRIPTEN_ROOT' in em_config: - # Old style (but can be there as a result from previous activation, so do last) - env.PrependENVPath('PATH', em_config.get('EMSCRIPTEN_ROOT')) - else: - raise RuntimeError("'BINARYEN_ROOT' or 'EMSCRIPTEN_ROOT' missing in Emscripten configuration file '%s'" % em_config_file) + # LTO + if env['use_lto']: + env.Append(CCFLAGS=['-s', 'WASM_OBJECT_FILES=0']) + env.Append(LINKFLAGS=['-s', 'WASM_OBJECT_FILES=0']) + env.Append(LINKFLAGS=['--llvm-lto', '1']) + + # Closure compiler + if env['use_closure_compiler']: + # For emscripten support code. + env.Append(LINKFLAGS=['--closure', '1']) + # Register builder for our Engine files + jscc = env.Builder(generator=run_closure_compiler, suffix='.cc.js', src_suffix='.js') + env.Append(BUILDERS = {'BuildJS' : jscc}) + + # Add method that joins/compiles our Engine files. + env.AddMethod(create_engine_file, "CreateEngineFile") + + # Closure compiler extern and support for ecmascript specs (const, let, etc). + env['ENV']['EMCC_CLOSURE_ARGS'] = '--language_in ECMASCRIPT6' + + em_config = parse_config() + env.PrependENVPath('PATH', em_config['EMCC_ROOT']) env['CC'] = 'emcc' env['CXX'] = 'em++' @@ -104,44 +124,31 @@ def configure(env): env['LIBPREFIXES'] = ['$LIBPREFIX'] env['LIBSUFFIXES'] = ['$LIBSUFFIX'] - ## Compile flags - env.Prepend(CPPPATH=['#platform/javascript']) env.Append(CPPDEFINES=['JAVASCRIPT_ENABLED', 'UNIX_ENABLED']) - # No multi-threading (SharedArrayBuffer) available yet, - # once feasible also consider memory buffer size issues. - env.Append(CPPDEFINES=['NO_THREADS']) - - # Disable exceptions and rtti on non-tools (template) builds - if not env['tools']: - # These flags help keep the file size down. - env.Append(CCFLAGS=['-fno-exceptions', '-fno-rtti']) - # Don't use dynamic_cast, necessary with no-rtti. - env.Append(CPPDEFINES=['NO_SAFE_CAST']) - if env['javascript_eval']: env.Append(CPPDEFINES=['JAVASCRIPT_EVAL_ENABLED']) - ## Link flags + # Thread support (via SharedArrayBuffer). + if env['threads_enabled']: + env.Append(CPPDEFINES=['PTHREAD_NO_RENAME']) + env.Append(CCFLAGS=['-s', 'USE_PTHREADS=1']) + env.Append(LINKFLAGS=['-s', 'USE_PTHREADS=1']) + env.Append(LINKFLAGS=['-s', 'PTHREAD_POOL_SIZE=4']) + env.Append(LINKFLAGS=['-s', 'WASM_MEM_MAX=2048MB']) + else: + env.Append(CPPDEFINES=['NO_THREADS']) + + # Reduce code size by generating less support code (e.g. skip NodeJS support). + env.Append(LINKFLAGS=['-s', 'ENVIRONMENT=web,worker']) # We use IDBFS in javascript_main.cpp. Since Emscripten 1.39.1 it needs to # be linked explicitly. env.Append(LIBS=['idbfs.js']) env.Append(LINKFLAGS=['-s', 'BINARYEN=1']) - - # Only include the JavaScript support code for the web environment - # (i.e. exclude Node.js and other unused environments). - # This makes the JavaScript support code about 4 KB smaller. - env.Append(LINKFLAGS=['-s', 'ENVIRONMENT=web']) - - # This needs to be defined for Emscripten using 'fastcomp' (default pre-1.39.0) - # and undefined if using 'upstream'. And to make things simple, earlier - # Emscripten versions didn't include 'fastcomp' in their path, so we check - # against the presence of 'upstream' to conditionally add the flag. - if not "upstream" in em_config['EMSCRIPTEN_ROOT']: - env.Append(LINKFLAGS=['-s', 'BINARYEN_TRAP_MODE=\'clamp\'']) + env.Append(LINKFLAGS=['-s', 'MODULARIZE=1', '-s', 'EXPORT_NAME="Godot"']) # Allow increasing memory buffer size during runtime. This is efficient # when using WebAssembly (in comparison to asm.js) and works well for @@ -153,8 +160,5 @@ def configure(env): env.Append(LINKFLAGS=['-s', 'INVOKE_RUN=0']) - # TODO: Reevaluate usage of this setting now that engine.js manages engine runtime. - env.Append(LINKFLAGS=['-s', 'NO_EXIT_RUNTIME=1']) - - #adding flag due to issue with emscripten 1.38.41 callMain method https://github.com/emscripten-core/emscripten/blob/incoming/ChangeLog.md#v13841-08072019 - env.Append(LINKFLAGS=['-s', 'EXTRA_EXPORTED_RUNTIME_METHODS=["callMain"]']) + # callMain for manual start, FS for preloading. + env.Append(LINKFLAGS=['-s', 'EXTRA_EXPORTED_RUNTIME_METHODS=["callMain", "FS"]']) diff --git a/platform/javascript/emscripten_helpers.py b/platform/javascript/emscripten_helpers.py new file mode 100644 index 0000000000..bda5b40a74 --- /dev/null +++ b/platform/javascript/emscripten_helpers.py @@ -0,0 +1,37 @@ +import os + +def parse_config(): + em_config_file = os.getenv('EM_CONFIG') or os.path.expanduser('~/.emscripten') + if not os.path.exists(em_config_file): + raise RuntimeError("Emscripten configuration file '%s' does not exist" % em_config_file) + + normalized = {} + em_config = {} + with open(em_config_file) as f: + try: + # Emscripten configuration file is a Python file with simple assignments. + exec(f.read(), em_config) + except StandardError as e: + raise RuntimeError("Emscripten configuration file '%s' is invalid:\n%s" % (em_config_file, e)) + normalized['EMCC_ROOT'] = em_config.get('EMSCRIPTEN_ROOT') + normalized['NODE_JS'] = em_config.get('NODE_JS') + normalized['CLOSURE_BIN'] = os.path.join(normalized['EMCC_ROOT'], 'node_modules', '.bin', 'google-closure-compiler') + return normalized + + +def run_closure_compiler(target, source, env, for_signature): + cfg = parse_config() + cmd = [cfg['NODE_JS'], cfg['CLOSURE_BIN']] + cmd.extend(['--compilation_level', 'ADVANCED_OPTIMIZATIONS']) + for f in env['JSEXTERNS']: + cmd.extend(['--externs', f.get_abspath()]) + for f in source: + cmd.extend(['--js', f.get_abspath()]) + cmd.extend(['--js_output_file', target[0].get_abspath()]) + return ' '.join(cmd) + + +def create_engine_file(env, target, source, externs): + if env['use_closure_compiler']: + return env.BuildJS(target, source, JSEXTERNS=externs) + return env.Textfile(target, [env.File(s) for s in source]) diff --git a/platform/javascript/engine.js b/platform/javascript/engine.js deleted file mode 100644 index 227accadb0..0000000000 --- a/platform/javascript/engine.js +++ /dev/null @@ -1,411 +0,0 @@ - // The following is concatenated with generated code, and acts as the end - // of a wrapper for said code. See pre.js for the other part of the - // wrapper. - exposedLibs['PATH'] = PATH; - exposedLibs['FS'] = FS; - return Module; - }, -}; - -(function() { - var engine = Engine; - - var DOWNLOAD_ATTEMPTS_MAX = 4; - - var basePath = null; - var wasmFilenameExtensionOverride = null; - var engineLoadPromise = null; - - var loadingFiles = {}; - - function getPathLeaf(path) { - - while (path.endsWith('/')) - path = path.slice(0, -1); - return path.slice(path.lastIndexOf('/') + 1); - } - - function getBasePath(path) { - - if (path.endsWith('/')) - path = path.slice(0, -1); - if (path.lastIndexOf('.') > path.lastIndexOf('/')) - path = path.slice(0, path.lastIndexOf('.')); - return path; - } - - function getBaseName(path) { - - return getPathLeaf(getBasePath(path)); - } - - Engine = function Engine() { - - this.rtenv = null; - - var LIBS = {}; - - var initPromise = null; - var unloadAfterInit = true; - - var preloadedFiles = []; - - var resizeCanvasOnStart = true; - var progressFunc = null; - var preloadProgressTracker = {}; - var lastProgress = { loaded: 0, total: 0 }; - - var canvas = null; - var executableName = null; - var locale = null; - var stdout = null; - var stderr = null; - - this.init = function(newBasePath) { - - if (!initPromise) { - initPromise = Engine.load(newBasePath).then( - instantiate.bind(this) - ); - requestAnimationFrame(animateProgress); - if (unloadAfterInit) - initPromise.then(Engine.unloadEngine); - } - return initPromise; - }; - - function instantiate(wasmBuf) { - - var rtenvProps = { - engine: this, - ENV: {}, - }; - if (typeof stdout === 'function') - rtenvProps.print = stdout; - if (typeof stderr === 'function') - rtenvProps.printErr = stderr; - rtenvProps.instantiateWasm = function(imports, onSuccess) { - WebAssembly.instantiate(wasmBuf, imports).then(function(result) { - onSuccess(result.instance); - }); - return {}; - }; - - return new Promise(function(resolve, reject) { - rtenvProps.onRuntimeInitialized = resolve; - rtenvProps.onAbort = reject; - rtenvProps.thisProgram = executableName; - rtenvProps.engine.rtenv = Engine.RuntimeEnvironment(rtenvProps, LIBS); - }); - } - - this.preloadFile = function(pathOrBuffer, destPath) { - - if (pathOrBuffer instanceof ArrayBuffer) { - pathOrBuffer = new Uint8Array(pathOrBuffer); - } else if (ArrayBuffer.isView(pathOrBuffer)) { - pathOrBuffer = new Uint8Array(pathOrBuffer.buffer); - } - if (pathOrBuffer instanceof Uint8Array) { - preloadedFiles.push({ - path: destPath, - buffer: pathOrBuffer - }); - return Promise.resolve(); - } else if (typeof pathOrBuffer === 'string') { - return loadPromise(pathOrBuffer, preloadProgressTracker).then(function(xhr) { - preloadedFiles.push({ - path: destPath || pathOrBuffer, - buffer: xhr.response - }); - }); - } else { - throw Promise.reject("Invalid object for preloading"); - } - }; - - this.start = function() { - - return this.init().then( - Function.prototype.apply.bind(synchronousStart, this, arguments) - ); - }; - - this.startGame = function(execName, mainPack) { - - executableName = execName; - var mainArgs = [ '--main-pack', getPathLeaf(mainPack) ]; - - return Promise.all([ - this.init(getBasePath(execName)), - this.preloadFile(mainPack, getPathLeaf(mainPack)) - ]).then( - Function.prototype.apply.bind(synchronousStart, this, mainArgs) - ); - }; - - function synchronousStart() { - - if (canvas instanceof HTMLCanvasElement) { - this.rtenv.canvas = canvas; - } else { - var firstCanvas = document.getElementsByTagName('canvas')[0]; - if (firstCanvas instanceof HTMLCanvasElement) { - this.rtenv.canvas = firstCanvas; - } else { - throw new Error("No canvas found"); - } - } - - var actualCanvas = this.rtenv.canvas; - // canvas can grab focus on click - if (actualCanvas.tabIndex < 0) { - actualCanvas.tabIndex = 0; - } - // necessary to calculate cursor coordinates correctly - actualCanvas.style.padding = 0; - actualCanvas.style.borderWidth = 0; - actualCanvas.style.borderStyle = 'none'; - // disable right-click context menu - actualCanvas.addEventListener('contextmenu', function(ev) { - ev.preventDefault(); - }, false); - // until context restoration is implemented - actualCanvas.addEventListener('webglcontextlost', function(ev) { - alert("WebGL context lost, please reload the page"); - ev.preventDefault(); - }, false); - - if (locale) { - this.rtenv.locale = locale; - } else { - this.rtenv.locale = navigator.languages ? navigator.languages[0] : navigator.language; - } - this.rtenv.locale = this.rtenv.locale.split('.')[0]; - this.rtenv.resizeCanvasOnStart = resizeCanvasOnStart; - - preloadedFiles.forEach(function(file) { - var dir = LIBS.PATH.dirname(file.path); - try { - LIBS.FS.stat(dir); - } catch (e) { - if (e.code !== 'ENOENT') { - throw e; - } - LIBS.FS.mkdirTree(dir); - } - // With memory growth, canOwn should be false. - LIBS.FS.createDataFile(file.path, null, new Uint8Array(file.buffer), true, true, false); - }, this); - - preloadedFiles = null; - initPromise = null; - this.rtenv.callMain(arguments); - } - - this.setProgressFunc = function(func) { - progressFunc = func; - }; - - this.setResizeCanvasOnStart = function(enabled) { - resizeCanvasOnStart = enabled; - }; - - function animateProgress() { - - var loaded = 0; - var total = 0; - var totalIsValid = true; - var progressIsFinal = true; - - [loadingFiles, preloadProgressTracker].forEach(function(tracker) { - Object.keys(tracker).forEach(function(file) { - if (!tracker[file].final) - progressIsFinal = false; - if (!totalIsValid || tracker[file].total === 0) { - totalIsValid = false; - total = 0; - } else { - total += tracker[file].total; - } - loaded += tracker[file].loaded; - }); - }); - if (loaded !== lastProgress.loaded || total !== lastProgress.total) { - lastProgress.loaded = loaded; - lastProgress.total = total; - if (typeof progressFunc === 'function') - progressFunc(loaded, total); - } - if (!progressIsFinal) - requestAnimationFrame(animateProgress); - } - - this.setCanvas = function(elem) { - canvas = elem; - }; - - this.setExecutableName = function(newName) { - - executableName = newName; - }; - - this.setLocale = function(newLocale) { - - locale = newLocale; - }; - - this.setUnloadAfterInit = function(enabled) { - - if (enabled && !unloadAfterInit && initPromise) { - initPromise.then(Engine.unloadEngine); - } - unloadAfterInit = enabled; - }; - - this.setStdoutFunc = function(func) { - - var print = function(text) { - if (arguments.length > 1) { - text = Array.prototype.slice.call(arguments).join(" "); - } - func(text); - }; - if (this.rtenv) - this.rtenv.print = print; - stdout = print; - }; - - this.setStderrFunc = function(func) { - - var printErr = function(text) { - if (arguments.length > 1) - text = Array.prototype.slice.call(arguments).join(" "); - func(text); - }; - if (this.rtenv) - this.rtenv.printErr = printErr; - stderr = printErr; - }; - - - }; // Engine() - - Engine.RuntimeEnvironment = engine.RuntimeEnvironment; - - Engine.isWebGLAvailable = function(majorVersion = 1) { - - var testContext = false; - try { - var testCanvas = document.createElement('canvas'); - if (majorVersion === 1) { - testContext = testCanvas.getContext('webgl') || testCanvas.getContext('experimental-webgl'); - } else if (majorVersion === 2) { - testContext = testCanvas.getContext('webgl2') || testCanvas.getContext('experimental-webgl2'); - } - } catch (e) {} - return !!testContext; - }; - - Engine.setWebAssemblyFilenameExtension = function(override) { - - if (String(override).length === 0) { - throw new Error('Invalid WebAssembly filename extension override'); - } - wasmFilenameExtensionOverride = String(override); - } - - Engine.load = function(newBasePath) { - - if (newBasePath !== undefined) basePath = getBasePath(newBasePath); - if (engineLoadPromise === null) { - if (typeof WebAssembly !== 'object') - return Promise.reject(new Error("Browser doesn't support WebAssembly")); - // TODO cache/retrieve module to/from idb - engineLoadPromise = loadPromise(basePath + '.' + (wasmFilenameExtensionOverride || 'wasm')).then(function(xhr) { - return xhr.response; - }); - engineLoadPromise = engineLoadPromise.catch(function(err) { - engineLoadPromise = null; - throw err; - }); - } - return engineLoadPromise; - }; - - Engine.unload = function() { - engineLoadPromise = null; - }; - - function loadPromise(file, tracker) { - if (tracker === undefined) - tracker = loadingFiles; - return new Promise(function(resolve, reject) { - loadXHR(resolve, reject, file, tracker); - }); - } - - function loadXHR(resolve, reject, file, tracker) { - - var xhr = new XMLHttpRequest; - xhr.open('GET', file); - if (!file.endsWith('.js')) { - xhr.responseType = 'arraybuffer'; - } - ['loadstart', 'progress', 'load', 'error', 'abort'].forEach(function(ev) { - xhr.addEventListener(ev, onXHREvent.bind(xhr, resolve, reject, file, tracker)); - }); - xhr.send(); - } - - function onXHREvent(resolve, reject, file, tracker, ev) { - - if (this.status >= 400) { - - if (this.status < 500 || ++tracker[file].attempts >= DOWNLOAD_ATTEMPTS_MAX) { - reject(new Error("Failed loading file '" + file + "': " + this.statusText)); - this.abort(); - return; - } else { - setTimeout(loadXHR.bind(null, resolve, reject, file, tracker), 1000); - } - } - - switch (ev.type) { - case 'loadstart': - if (tracker[file] === undefined) { - tracker[file] = { - total: ev.total, - loaded: ev.loaded, - attempts: 0, - final: false, - }; - } - break; - - case 'progress': - tracker[file].loaded = ev.loaded; - tracker[file].total = ev.total; - break; - - case 'load': - tracker[file].final = true; - resolve(this); - break; - - case 'error': - if (++tracker[file].attempts >= DOWNLOAD_ATTEMPTS_MAX) { - tracker[file].final = true; - reject(new Error("Failed loading file '" + file + "'")); - } else { - setTimeout(loadXHR.bind(null, resolve, reject, file, tracker), 1000); - } - break; - - case 'abort': - tracker[file].final = true; - reject(new Error("Loading file '" + file + "' was aborted.")); - break; - } - } -})(); diff --git a/platform/javascript/engine/engine.js b/platform/javascript/engine/engine.js new file mode 100644 index 0000000000..6d7509377f --- /dev/null +++ b/platform/javascript/engine/engine.js @@ -0,0 +1,184 @@ +Function('return this')()['Engine'] = (function() { + + var unloadAfterInit = true; + var canvas = null; + var resizeCanvasOnStart = false; + var customLocale = 'en_US'; + var wasmExt = '.wasm'; + + var preloader = new Preloader(); + var loader = new Loader(); + var rtenv = null; + + var executableName = ''; + var loadPath = ''; + var loadPromise = null; + var initPromise = null; + var stderr = null; + var stdout = null; + var progressFunc = null; + + function load(basePath) { + if (loadPromise == null) { + loadPath = basePath; + loadPromise = preloader.loadPromise(basePath + wasmExt); + preloader.setProgressFunc(progressFunc); + requestAnimationFrame(preloader.animateProgress); + } + return loadPromise; + }; + + function unload() { + loadPromise = null; + }; + + /** @constructor */ + function Engine() {}; + + Engine.prototype.init = /** @param {string=} basePath */ function(basePath) { + if (initPromise) { + return initPromise; + } + if (!loadPromise) { + if (!basePath) { + initPromise = Promise.reject(new Error("A base path must be provided when calling `init` and the engine is not loaded.")); + return initPromise; + } + load(basePath); + } + var config = {} + if (typeof stdout === 'function') + config.print = stdout; + if (typeof stderr === 'function') + config.printErr = stderr; + initPromise = loader.init(loadPromise, loadPath, config).then(function() { + return new Promise(function(resolve, reject) { + rtenv = loader.env; + if (unloadAfterInit) { + loadPromise = null; + } + resolve(); + }); + }); + return initPromise; + }; + + /** @type {function(string, string):Object} */ + Engine.prototype.preloadFile = function(file, path) { + return preloader.preload(file, path); + }; + + /** @type {function(...string):Object} */ + Engine.prototype.start = function() { + // Start from arguments. + var args = []; + for (var i = 0; i < arguments.length; i++) { + args.push(arguments[i]); + } + var me = this; + return new Promise(function(resolve, reject) { + return me.init().then(function() { + if (!(canvas instanceof HTMLCanvasElement)) { + canvas = Utils.findCanvas(); + } + rtenv['locale'] = customLocale; + rtenv['canvas'] = canvas; + rtenv['thisProgram'] = executableName; + rtenv['resizeCanvasOnStart'] = resizeCanvasOnStart; + loader.start(preloader.preloadedFiles, args).then(function() { + loader = null; + initPromise = null; + resolve(); + }); + }); + }); + }; + + Engine.prototype.startGame = function(execName, mainPack) { + // Start and init with execName as loadPath if not inited. + executableName = execName; + var me = this; + return Promise.all([ + this.init(execName), + this.preloadFile(mainPack, mainPack) + ]).then(function() { + return me.start('--main-pack', mainPack); + }); + }; + + Engine.prototype.setWebAssemblyFilenameExtension = function(override) { + if (String(override).length === 0) { + throw new Error('Invalid WebAssembly filename extension override'); + } + wasmExt = String(override); + }; + + Engine.prototype.setUnloadAfterInit = function(enabled) { + unloadAfterInit = enabled; + }; + + Engine.prototype.setCanvas = function(canvasElem) { + canvas = canvasElem; + }; + + Engine.prototype.setCanvasResizedOnStart = function(enabled) { + resizeCanvasOnStart = enabled; + }; + + Engine.prototype.setLocale = function(locale) { + customLocale = locale; + }; + + Engine.prototype.setExecutableName = function(newName) { + executableName = newName; + }; + + Engine.prototype.setProgressFunc = function(func) { + progressFunc = func; + } + + Engine.prototype.setStdoutFunc = function(func) { + + var print = function(text) { + if (arguments.length > 1) { + text = Array.prototype.slice.call(arguments).join(" "); + } + func(text); + }; + if (rtenv) + rtenv.print = print; + stdout = print; + }; + + Engine.prototype.setStderrFunc = function(func) { + + var printErr = function(text) { + if (arguments.length > 1) + text = Array.prototype.slice.call(arguments).join(" "); + func(text); + }; + if (rtenv) + rtenv.printErr = printErr; + stderr = printErr; + }; + + // Closure compiler exported engine methods. + /** @export */ + Engine['isWebGLAvailable'] = Utils.isWebGLAvailable; + Engine['load'] = load; + Engine['unload'] = unload; + Engine.prototype['init'] = Engine.prototype.init + Engine.prototype['preloadFile'] = Engine.prototype.preloadFile + Engine.prototype['start'] = Engine.prototype.start + Engine.prototype['startGame'] = Engine.prototype.startGame + Engine.prototype['setWebAssemblyFilenameExtension'] = Engine.prototype.setWebAssemblyFilenameExtension + Engine.prototype['setUnloadAfterInit'] = Engine.prototype.setUnloadAfterInit + Engine.prototype['setCanvas'] = Engine.prototype.setCanvas + Engine.prototype['setCanvasResizedOnStart'] = Engine.prototype.setCanvasResizedOnStart + Engine.prototype['setLocale'] = Engine.prototype.setLocale + Engine.prototype['setExecutableName'] = Engine.prototype.setExecutableName + Engine.prototype['setProgressFunc'] = Engine.prototype.setProgressFunc + Engine.prototype['setStdoutFunc'] = Engine.prototype.setStdoutFunc + Engine.prototype['setStderrFunc'] = Engine.prototype.setStderrFunc + return Engine; +})(); diff --git a/platform/javascript/engine/externs.js b/platform/javascript/engine/externs.js new file mode 100644 index 0000000000..1a94dd15ec --- /dev/null +++ b/platform/javascript/engine/externs.js @@ -0,0 +1,3 @@ +var Godot; +var WebAssembly = {}; +WebAssembly.instantiate = function(buffer, imports) {}; diff --git a/platform/javascript/engine/loader.js b/platform/javascript/engine/loader.js new file mode 100644 index 0000000000..d27fbf612e --- /dev/null +++ b/platform/javascript/engine/loader.js @@ -0,0 +1,33 @@ +var Loader = /** @constructor */ function() { + + this.env = null; + + this.init = function(loadPromise, basePath, config) { + var me = this; + return new Promise(function(resolve, reject) { + var cfg = config || {}; + cfg['locateFile'] = Utils.createLocateRewrite(basePath); + cfg['instantiateWasm'] = Utils.createInstantiatePromise(loadPromise); + loadPromise = null; + Godot(cfg).then(function(module) { + me.env = module; + resolve(); + }); + }); + } + + this.start = function(preloadedFiles, args) { + var me = this; + return new Promise(function(resolve, reject) { + if (!me.env) { + reject(new Error('The engine must be initialized before it can be started')); + } + preloadedFiles.forEach(function(file) { + Utils.copyToFS(me.env['FS'], file.path, file.buffer); + }); + preloadedFiles.length = 0; // Clear memory + me.env['callMain'](args); + resolve(); + }); + } +}; diff --git a/platform/javascript/engine/preloader.js b/platform/javascript/engine/preloader.js new file mode 100644 index 0000000000..17918eae38 --- /dev/null +++ b/platform/javascript/engine/preloader.js @@ -0,0 +1,139 @@ +var Preloader = /** @constructor */ function() { + + var DOWNLOAD_ATTEMPTS_MAX = 4; + var progressFunc = null; + var lastProgress = { loaded: 0, total: 0 }; + + var loadingFiles = {}; + this.preloadedFiles = []; + + function loadXHR(resolve, reject, file, tracker) { + var xhr = new XMLHttpRequest; + xhr.open('GET', file); + if (!file.endsWith('.js')) { + xhr.responseType = 'arraybuffer'; + } + ['loadstart', 'progress', 'load', 'error', 'abort'].forEach(function(ev) { + xhr.addEventListener(ev, onXHREvent.bind(xhr, resolve, reject, file, tracker)); + }); + xhr.send(); + } + + function onXHREvent(resolve, reject, file, tracker, ev) { + + if (this.status >= 400) { + + if (this.status < 500 || ++tracker[file].attempts >= DOWNLOAD_ATTEMPTS_MAX) { + reject(new Error("Failed loading file '" + file + "': " + this.statusText)); + this.abort(); + return; + } else { + setTimeout(loadXHR.bind(null, resolve, reject, file, tracker), 1000); + } + } + + switch (ev.type) { + case 'loadstart': + if (tracker[file] === undefined) { + tracker[file] = { + total: ev.total, + loaded: ev.loaded, + attempts: 0, + final: false, + }; + } + break; + + case 'progress': + tracker[file].loaded = ev.loaded; + tracker[file].total = ev.total; + break; + + case 'load': + tracker[file].final = true; + resolve(this); + break; + + case 'error': + if (++tracker[file].attempts >= DOWNLOAD_ATTEMPTS_MAX) { + tracker[file].final = true; + reject(new Error("Failed loading file '" + file + "'")); + } else { + setTimeout(loadXHR.bind(null, resolve, reject, file, tracker), 1000); + } + break; + + case 'abort': + tracker[file].final = true; + reject(new Error("Loading file '" + file + "' was aborted.")); + break; + } + } + + this.loadPromise = function(file) { + return new Promise(function(resolve, reject) { + loadXHR(resolve, reject, file, loadingFiles); + }); + } + + this.preload = function(pathOrBuffer, destPath) { + if (pathOrBuffer instanceof ArrayBuffer) { + pathOrBuffer = new Uint8Array(pathOrBuffer); + } else if (ArrayBuffer.isView(pathOrBuffer)) { + pathOrBuffer = new Uint8Array(pathOrBuffer.buffer); + } + if (pathOrBuffer instanceof Uint8Array) { + this.preloadedFiles.push({ + path: destPath, + buffer: pathOrBuffer + }); + return Promise.resolve(); + } else if (typeof pathOrBuffer === 'string') { + var me = this; + return this.loadPromise(pathOrBuffer).then(function(xhr) { + me.preloadedFiles.push({ + path: destPath || pathOrBuffer, + buffer: xhr.response + }); + return Promise.resolve(); + }); + } else { + throw Promise.reject("Invalid object for preloading"); + } + }; + + var animateProgress = function() { + + var loaded = 0; + var total = 0; + var totalIsValid = true; + var progressIsFinal = true; + + Object.keys(loadingFiles).forEach(function(file) { + const stat = loadingFiles[file]; + if (!stat.final) { + progressIsFinal = false; + } + if (!totalIsValid || stat.total === 0) { + totalIsValid = false; + total = 0; + } else { + total += stat.total; + } + loaded += stat.loaded; + }); + if (loaded !== lastProgress.loaded || total !== lastProgress.total) { + lastProgress.loaded = loaded; + lastProgress.total = total; + if (typeof progressFunc === 'function') + progressFunc(loaded, total); + } + if (!progressIsFinal) + requestAnimationFrame(animateProgress); + } + this.animateProgress = animateProgress; // Also exposed to start it. + + this.setProgressFunc = function(callback) { + progressFunc = callback; + } +}; diff --git a/platform/javascript/engine/utils.js b/platform/javascript/engine/utils.js new file mode 100644 index 0000000000..fdff90a923 --- /dev/null +++ b/platform/javascript/engine/utils.js @@ -0,0 +1,69 @@ +var Utils = { + + createLocateRewrite: function(execName) { + function rw(path) { + if (path.endsWith('.worker.js')) { + return execName + '.worker.js'; + } else if (path.endsWith('.js')) { + return execName + '.js'; + } else if (path.endsWith('.wasm')) { + return execName + '.wasm'; + } + } + return rw; + }, + + createInstantiatePromise: function(wasmLoader) { + function instantiateWasm(imports, onSuccess) { + wasmLoader.then(function(xhr) { + WebAssembly.instantiate(xhr.response, imports).then(function(result) { + onSuccess(result['instance'], result['module']); + }); + }); + wasmLoader = null; + return {}; + }; + + return instantiateWasm; + }, + + copyToFS: function(fs, path, buffer) { + var p = path.lastIndexOf("/"); + var dir = "/"; + if (p > 0) { + dir = path.slice(0, path.lastIndexOf("/")); + } + try { + fs.stat(dir); + } catch (e) { + if (e.errno !== 44) { // 'ENOENT', see https://github.com/emscripten-core/emscripten/blob/master/system/lib/libc/musl/arch/emscripten/bits/errno.h + throw e; + } + fs['mkdirTree'](dir); + } + // With memory growth, canOwn should be false. + fs['writeFile'](path, new Uint8Array(buffer), {'flags': 'wx+'}); + }, + + findCanvas: function() { + var nodes = document.getElementsByTagName('canvas'); + if (nodes.length && nodes[0] instanceof HTMLCanvasElement) { + return nodes[0]; + } + throw new Error("No canvas found"); + }, + + isWebGLAvailable: function(majorVersion = 1) { + + var testContext = false; + try { + var testCanvas = document.createElement('canvas'); + if (majorVersion === 1) { + testContext = testCanvas.getContext('webgl') || testCanvas.getContext('experimental-webgl'); + } else if (majorVersion === 2) { + testContext = testCanvas.getContext('webgl2') || testCanvas.getContext('experimental-webgl2'); + } + } catch (e) {} + return !!testContext; + } +}; diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index f0326d5027..da61425747 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -94,6 +94,9 @@ public: } else if (req[1] == basereq + ".js") { filepath += ".js"; ctype = "application/javascript"; + } else if (req[1] == basereq + ".worker.js") { + filepath += ".worker.js"; + ctype = "application/javascript"; } else if (req[1] == basereq + ".pck") { filepath += ".pck"; ctype = "application/octet-stream"; @@ -432,6 +435,10 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese } else if (file == "godot.js") { file = p_path.get_file().get_basename() + ".js"; + } else if (file == "godot.worker.js") { + + file = p_path.get_file().get_basename() + ".worker.js"; + } else if (file == "godot.wasm") { file = p_path.get_file().get_basename() + ".wasm"; @@ -563,6 +570,7 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese // Export generates several files, clean them up on failure. DirAccess::remove_file_or_error(basepath + ".html"); DirAccess::remove_file_or_error(basepath + ".js"); + DirAccess::remove_file_or_error(basepath + ".worker.js"); DirAccess::remove_file_or_error(basepath + ".pck"); DirAccess::remove_file_or_error(basepath + ".png"); DirAccess::remove_file_or_error(basepath + ".wasm"); diff --git a/platform/javascript/id_handler.js b/platform/javascript/id_handler.js index 3851123ed1..67d29075b8 100644 --- a/platform/javascript/id_handler.js +++ b/platform/javascript/id_handler.js @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -var IDHandler = function() { +var IDHandler = /** @constructor */ function() { var ids = {}; var size = 0; diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 9ba0223387..db90b01f8f 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -470,7 +470,7 @@ void OS_JavaScript::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_s if (p_cursor.is_valid()) { - Map<CursorShape, Vector<Variant> >::Element *cursor_c = cursors_cache.find(p_shape); + Map<CursorShape, Vector<Variant>>::Element *cursor_c = cursors_cache.find(p_shape); if (cursor_c) { if (cursor_c->get()[0] == p_cursor && cursor_c->get()[1] == p_hotspot) { @@ -887,7 +887,7 @@ int OS_JavaScript::get_current_video_driver() const { void OS_JavaScript::initialize_core() { OS_Unix::initialize_core(); - FileAccess::make_default<FileAccessBufferedFA<FileAccessUnix> >(FileAccess::ACCESS_RESOURCES); + FileAccess::make_default<FileAccessBufferedFA<FileAccessUnix>>(FileAccess::ACCESS_RESOURCES); } Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { @@ -935,6 +935,7 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, if (p_desired.fullscreen) { /* clang-format off */ EM_ASM({ + const canvas = Module.canvas; (canvas.requestFullscreen || canvas.msRequestFullscreen || canvas.mozRequestFullScreen || canvas.mozRequestFullscreen || canvas.webkitRequestFullscreen diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index 5319ea121c..ed59477914 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -52,7 +52,7 @@ class OS_JavaScript : public OS_Unix { Ref<InputEventKey> deferred_key_event; CursorShape cursor_shape; String cursors[CURSOR_MAX]; - Map<CursorShape, Vector<Variant> > cursors_cache; + Map<CursorShape, Vector<Variant>> cursors_cache; Point2 touches[32]; Point2i last_click_pos; diff --git a/platform/javascript/pre.js b/platform/javascript/pre.js deleted file mode 100644 index a870e676ea..0000000000 --- a/platform/javascript/pre.js +++ /dev/null @@ -1,5 +0,0 @@ -var Engine = { - RuntimeEnvironment: function(Module, exposedLibs) { - // The above is concatenated with generated code, and acts as the start of - // a wrapper for said code. See engine.js for the other part of the - // wrapper. diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 3140d9bac4..e865c3078f 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -124,7 +124,7 @@ public: CursorShape cursor_shape; NSCursor *cursors[CURSOR_MAX]; - Map<CursorShape, Vector<Variant> > cursors_cache; + Map<CursorShape, Vector<Variant>> cursors_cache; MouseMode mouse_mode; String title; @@ -180,7 +180,7 @@ public: } }; - Map<String, Vector<GlobalMenuItem> > global_menus; + Map<String, Vector<GlobalMenuItem>> global_menus; void _update_global_menu(); diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 4c70beee00..8ba8ca8a33 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -1365,7 +1365,7 @@ void OS_OSX::_update_global_menu() { for (int i = 1; i < [main_menu numberOfItems]; i++) { [main_menu removeItemAtIndex:i]; } - for (Map<String, Vector<GlobalMenuItem> >::Element *E = global_menus.front(); E; E = E->next()) { + for (Map<String, Vector<GlobalMenuItem>>::Element *E = global_menus.front(); E; E = E->next()) { if (E->key() != "_dock") { NSMenu *menu = [[[NSMenu alloc] initWithTitle:[NSString stringWithUTF8String:E->key().utf8().get_data()]] autorelease]; for (int i = 0; i < E->get().size(); i++) { @@ -1835,7 +1835,7 @@ void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c if (p_cursor.is_valid()) { - Map<CursorShape, Vector<Variant> >::Element *cursor_c = cursors_cache.find(p_shape); + Map<CursorShape, Vector<Variant>>::Element *cursor_c = cursors_cache.find(p_shape); if (cursor_c) { if (cursor_c->get()[0] == p_cursor && cursor_c->get()[1] == p_hotspot) { diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index a112f26ac4..041a5bffa6 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -2518,7 +2518,7 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap if (p_cursor.is_valid()) { - Map<CursorShape, Vector<Variant> >::Element *cursor_c = cursors_cache.find(p_shape); + Map<CursorShape, Vector<Variant>>::Element *cursor_c = cursors_cache.find(p_shape); if (cursor_c) { if (cursor_c->get()[0] == p_cursor && cursor_c->get()[1] == p_hotspot) { diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 6c3769c98c..8506aa7b20 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -232,7 +232,7 @@ class OS_Windows : public OS { HCURSOR cursors[CURSOR_MAX] = { NULL }; CursorShape cursor_shape; - Map<CursorShape, Vector<Variant> > cursors_cache; + Map<CursorShape, Vector<Variant>> cursors_cache; InputDefault *input; JoypadWindows *joypad; diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index c74981fd55..e1f7691cf6 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -2012,8 +2012,10 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { // is correct, but the xorg developers are // not very helpful today. - ::Time tresh = ABSDIFF(peek_event.xkey.time, xkeyevent->time); - if (peek_event.type == KeyPress && tresh < 5) { +#define ABSDIFF(x, y) (((x) < (y)) ? ((y) - (x)) : ((x) - (y))) + ::Time threshold = ABSDIFF(peek_event.xkey.time, xkeyevent->time); +#undef ABSDIFF + if (peek_event.type == KeyPress && threshold < 5) { KeySym rk; XLookupString((XKeyEvent *)&peek_event, str, 256, &rk, NULL); if (rk == keysym_keycode) { @@ -3032,7 +3034,7 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c if (p_cursor.is_valid()) { - Map<CursorShape, Vector<Variant> >::Element *cursor_c = cursors_cache.find(p_shape); + Map<CursorShape, Vector<Variant>>::Element *cursor_c = cursors_cache.find(p_shape); if (cursor_c) { if (cursor_c->get()[0] == p_cursor && cursor_c->get()[1] == p_hotspot) { diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 55d24d64a3..997a6cc053 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -179,7 +179,7 @@ class OS_X11 : public OS_Unix { Cursor cursors[CURSOR_MAX]; Cursor null_cursor; CursorShape current_cursor; - Map<CursorShape, Vector<Variant> > cursors_cache; + Map<CursorShape, Vector<Variant>> cursors_cache; InputDefault *input; diff --git a/scene/2d/animated_sprite.h b/scene/2d/animated_sprite.h index 37d093e3d8..e5d015b07c 100644 --- a/scene/2d/animated_sprite.h +++ b/scene/2d/animated_sprite.h @@ -42,7 +42,7 @@ class SpriteFrames : public Resource { float speed; bool loop; - Vector<Ref<Texture2D> > frames; + Vector<Ref<Texture2D>> frames; Anim() { loop = true; diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index 4edf92197e..e9dfb94cb2 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -50,7 +50,7 @@ void CollisionPolygon2D::_build_polygon() { //here comes the sun, lalalala //decompose concave into multiple convex polygons and add them - Vector<Vector<Vector2> > decomp = _decompose_in_convex(); + Vector<Vector<Vector2>> decomp = _decompose_in_convex(); for (int i = 0; i < decomp.size(); i++) { Ref<ConvexPolygonShape2D> convex = memnew(ConvexPolygonShape2D); convex->set_points(decomp[i]); @@ -76,8 +76,8 @@ void CollisionPolygon2D::_build_polygon() { } } -Vector<Vector<Vector2> > CollisionPolygon2D::_decompose_in_convex() { - Vector<Vector<Vector2> > decomp = Geometry::decompose_polygon_in_convex(polygon); +Vector<Vector<Vector2>> CollisionPolygon2D::_decompose_in_convex() { + Vector<Vector<Vector2>> decomp = Geometry::decompose_polygon_in_convex(polygon); return decomp; } @@ -148,7 +148,7 @@ void CollisionPolygon2D::_notification(int p_what) { #define DEBUG_DECOMPOSE #if defined(TOOLS_ENABLED) && defined(DEBUG_DECOMPOSE) - Vector<Vector<Vector2> > decomp = _decompose_in_convex(); + Vector<Vector<Vector2>> decomp = _decompose_in_convex(); Color c(0.4, 0.9, 0.1); for (int i = 0; i < decomp.size(); i++) { diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h index d8dfec8fd2..92a2758813 100644 --- a/scene/2d/collision_polygon_2d.h +++ b/scene/2d/collision_polygon_2d.h @@ -56,7 +56,7 @@ protected: bool one_way_collision; float one_way_collision_margin; - Vector<Vector<Vector2> > _decompose_in_convex(); + Vector<Vector<Vector2>> _decompose_in_convex(); void _build_polygon(); diff --git a/scene/2d/navigation_polygon.h b/scene/2d/navigation_polygon.h index 579d6b0e0e..3d096ec91b 100644 --- a/scene/2d/navigation_polygon.h +++ b/scene/2d/navigation_polygon.h @@ -43,7 +43,7 @@ class NavigationPolygon : public Resource { Vector<int> indices; }; Vector<Polygon> polygons; - Vector<Vector<Vector2> > outlines; + Vector<Vector<Vector2>> outlines; mutable Rect2 item_rect; mutable bool rect_cache_dirty; diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 20e9f3ffcf..eb7aefb495 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -300,7 +300,7 @@ private: bool sync_to_physics; Vector<Collision> colliders; - Vector<Ref<KinematicCollision2D> > slide_colliders; + Vector<Ref<KinematicCollision2D>> slide_colliders; Ref<KinematicCollision2D> motion_cache; _FORCE_INLINE_ bool _ignores_mode(Physics2DServer::BodyMode) const; diff --git a/scene/3d/collision_polygon.cpp b/scene/3d/collision_polygon.cpp index 636b859477..24c3a9eb41 100644 --- a/scene/3d/collision_polygon.cpp +++ b/scene/3d/collision_polygon.cpp @@ -44,7 +44,7 @@ void CollisionPolygon::_build_polygon() { if (polygon.size() == 0) return; - Vector<Vector<Vector2> > decomp = Geometry::decompose_polygon_in_convex(polygon); + Vector<Vector<Vector2>> decomp = Geometry::decompose_polygon_in_convex(polygon); if (decomp.size() == 0) return; diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h index 354eaad7c0..f991843883 100644 --- a/scene/3d/gi_probe.h +++ b/scene/3d/gi_probe.h @@ -135,7 +135,7 @@ private: struct PlotMesh { Ref<Material> override_material; - Vector<Ref<Material> > instance_materials; + Vector<Ref<Material>> instance_materials; Ref<Mesh> mesh; Transform local_xform; }; diff --git a/scene/3d/immediate_geometry.h b/scene/3d/immediate_geometry.h index 77a20e8d4d..f9222c75fa 100644 --- a/scene/3d/immediate_geometry.h +++ b/scene/3d/immediate_geometry.h @@ -41,7 +41,7 @@ class ImmediateGeometry : public GeometryInstance { RID im; //a list of textures drawn need to be kept, to avoid references // in VisualServer from becoming invalid if the texture is no longer used - List<Ref<Texture2D> > cached_textures; + List<Ref<Texture2D>> cached_textures; bool empty; AABB aabb; diff --git a/scene/3d/mesh_instance.h b/scene/3d/mesh_instance.h index d49d9ed98f..a6190e7660 100644 --- a/scene/3d/mesh_instance.h +++ b/scene/3d/mesh_instance.h @@ -58,7 +58,7 @@ protected: }; Map<StringName, BlendShapeTrack> blend_shape_tracks; - Vector<Ref<Material> > materials; + Vector<Ref<Material>> materials; void _mesh_changed(); void _resolve_skeleton_path(); diff --git a/scene/3d/particles.h b/scene/3d/particles.h index 95c6de15ec..cf461f25e9 100644 --- a/scene/3d/particles.h +++ b/scene/3d/particles.h @@ -69,7 +69,7 @@ private: DrawOrder draw_order; - Vector<Ref<Mesh> > draw_passes; + Vector<Ref<Mesh>> draw_passes; protected: static void _bind_methods(); diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h index 5362baf8ee..90de1ffce6 100644 --- a/scene/3d/physics_body.h +++ b/scene/3d/physics_body.h @@ -293,7 +293,7 @@ private: bool on_ceiling; bool on_wall; Vector<Collision> colliders; - Vector<Ref<KinematicCollision> > slide_colliders; + Vector<Ref<KinematicCollision>> slide_colliders; Ref<KinematicCollision> motion_cache; _FORCE_INLINE_ bool _ignores_mode(PhysicsServer::BodyMode) const; diff --git a/scene/3d/ray_cast.cpp b/scene/3d/ray_cast.cpp index be1426f13c..f6eb3d954a 100644 --- a/scene/3d/ray_cast.cpp +++ b/scene/3d/ray_cast.cpp @@ -186,7 +186,7 @@ void RayCast::_notification(int p_what) { _update_raycast_state(); if (prev_collision_state != collided && get_tree()->is_debugging_collisions_hint()) { if (debug_material.is_valid()) { - Ref<StandardMaterial3D> line_material = static_cast<Ref<StandardMaterial3D> >(debug_material); + Ref<StandardMaterial3D> line_material = static_cast<Ref<StandardMaterial3D>>(debug_material); line_material->set_albedo(collided ? Color(1.0, 0, 0) : Color(1.0, 0.8, 0.6)); } } @@ -335,7 +335,7 @@ void RayCast::_create_debug_shape() { if (!debug_material.is_valid()) { debug_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); - Ref<StandardMaterial3D> line_material = static_cast<Ref<StandardMaterial3D> >(debug_material); + Ref<StandardMaterial3D> line_material = static_cast<Ref<StandardMaterial3D>>(debug_material); line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); line_material->set_albedo(Color(1.0, 0.8, 0.6)); } diff --git a/scene/3d/soft_body.cpp b/scene/3d/soft_body.cpp index 3859a278ef..65f868aed4 100644 --- a/scene/3d/soft_body.cpp +++ b/scene/3d/soft_body.cpp @@ -479,7 +479,7 @@ void SoftBody::become_mesh_owner() { if (!mesh_owner) { mesh_owner = true; - Vector<Ref<Material> > copy_materials; + Vector<Ref<Material>> copy_materials; copy_materials.append_array(materials); ERR_FAIL_COND(!mesh->get_surface_count()); diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp index 0257e6e83d..203c3cd812 100644 --- a/scene/3d/voxelizer.cpp +++ b/scene/3d/voxelizer.cpp @@ -569,7 +569,7 @@ Voxelizer::MaterialCache Voxelizer::_get_material_cache(Ref<Material> p_material return mc; } -void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material> > &p_materials, const Ref<Material> &p_override_material) { +void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material>> &p_materials, const Ref<Material> &p_override_material) { for (int i = 0; i < p_mesh->get_surface_count(); i++) { diff --git a/scene/3d/voxelizer.h b/scene/3d/voxelizer.h index 1d50f1cd18..af9237ae7b 100644 --- a/scene/3d/voxelizer.h +++ b/scene/3d/voxelizer.h @@ -125,7 +125,7 @@ private: public: void begin_bake(int p_subdiv, const AABB &p_bounds); - void plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material> > &p_materials, const Ref<Material> &p_override_material); + void plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material>> &p_materials, const Ref<Material> &p_override_material); void end_bake(); int get_gi_probe_octree_depth() const; diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index fbd9a2aa7d..ce1e75a61d 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -565,6 +565,27 @@ void AnimationNodeStateMachine::add_node(const StringName &p_name, Ref<Animation p_node->connect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED); } +void AnimationNodeStateMachine::replace_node(const StringName &p_name, Ref<AnimationNode> p_node) { + + ERR_FAIL_COND(states.has(p_name) == false); + ERR_FAIL_COND(p_node.is_null()); + ERR_FAIL_COND(String(p_name).find("/") != -1); + + { + Ref<AnimationNode> node = states[p_name].node; + if (node.is_valid()) { + node->disconnect_compat("tree_changed", this, "_tree_changed"); + } + } + + states[p_name].node = p_node; + + emit_changed(); + emit_signal("tree_changed"); + + p_node->connect_compat("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED); +} + Ref<AnimationNode> AnimationNodeStateMachine::get_node(const StringName &p_name) const { ERR_FAIL_COND_V(!states.has(p_name), Ref<AnimationNode>()); @@ -949,6 +970,7 @@ void AnimationNodeStateMachine::_tree_changed() { void AnimationNodeStateMachine::_bind_methods() { ClassDB::bind_method(D_METHOD("add_node", "name", "node", "position"), &AnimationNodeStateMachine::add_node, DEFVAL(Vector2())); + ClassDB::bind_method(D_METHOD("replace_node", "name", "node"), &AnimationNodeStateMachine::replace_node); ClassDB::bind_method(D_METHOD("get_node", "name"), &AnimationNodeStateMachine::get_node); ClassDB::bind_method(D_METHOD("remove_node", "name"), &AnimationNodeStateMachine::remove_node); ClassDB::bind_method(D_METHOD("rename_node", "name", "new_name"), &AnimationNodeStateMachine::rename_node); diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h index 55c9c3f00e..27a4451f08 100644 --- a/scene/animation/animation_node_state_machine.h +++ b/scene/animation/animation_node_state_machine.h @@ -178,6 +178,7 @@ public: virtual Variant get_parameter_default_value(const StringName &p_parameter) const; void add_node(const StringName &p_name, Ref<AnimationNode> p_node, const Vector2 &p_position = Vector2()); + void replace_node(const StringName &p_name, Ref<AnimationNode> p_node); Ref<AnimationNode> get_node(const StringName &p_name) const; void remove_node(const StringName &p_name); void rename_node(const StringName &p_name, const StringName &p_new_name); diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index 8769e2c61d..742942fcda 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -285,7 +285,7 @@ private: void _tree_changed(); void _update_properties(); List<PropertyInfo> properties; - HashMap<StringName, HashMap<StringName, StringName> > property_parent_map; + HashMap<StringName, HashMap<StringName, StringName>> property_parent_map; HashMap<StringName, Variant> property_map; struct Activity { @@ -293,7 +293,7 @@ private: float activity; }; - HashMap<StringName, Vector<Activity> > input_activity_map; + HashMap<StringName, Vector<Activity>> input_activity_map; HashMap<StringName, Vector<Activity> *> input_activity_map_get; void _update_properties_for_node(const String &p_base_path, Ref<AnimationNode> node); diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp index 2a98b4cf22..7a184adc55 100644 --- a/scene/debugger/scene_debugger.cpp +++ b/scene/debugger/scene_debugger.cpp @@ -230,8 +230,8 @@ void SceneDebugger::remove_from_cache(const String &p_filename, Node *p_node) { if (!debugger) return; - Map<String, Set<Node *> > &edit_cache = debugger->live_scene_edit_cache; - Map<String, Set<Node *> >::Element *E = edit_cache.find(p_filename); + Map<String, Set<Node *>> &edit_cache = debugger->live_scene_edit_cache; + Map<String, Set<Node *>>::Element *E = edit_cache.find(p_filename); if (E) { E->get().erase(p_node); if (E->get().size() == 0) { @@ -239,8 +239,8 @@ void SceneDebugger::remove_from_cache(const String &p_filename, Node *p_node) { } } - Map<Node *, Map<ObjectID, Node *> > &remove_list = debugger->live_edit_remove_list; - Map<Node *, Map<ObjectID, Node *> >::Element *F = remove_list.find(p_node); + Map<Node *, Map<ObjectID, Node *>> &remove_list = debugger->live_edit_remove_list; + Map<Node *, Map<ObjectID, Node *>>::Element *F = remove_list.find(p_node); if (F) { for (Map<ObjectID, Node *>::Element *G = F->get().front(); G; G = G->next()) { @@ -293,8 +293,8 @@ SceneDebuggerObject::SceneDebuggerObject(ObjectID p_id) { } void SceneDebuggerObject::_parse_script_properties(Script *p_script, ScriptInstance *p_instance) { - typedef Map<const Script *, Set<StringName> > ScriptMemberMap; - typedef Map<const Script *, Map<StringName, Variant> > ScriptConstantsMap; + typedef Map<const Script *, Set<StringName>> ScriptMemberMap; + typedef Map<const Script *, Map<StringName, Variant>> ScriptConstantsMap; ScriptMemberMap members; if (p_instance) { @@ -519,7 +519,7 @@ void LiveEditor::_node_set_func(int p_id, const StringName &p_prop, const Varian if (scene_tree->root->has_node(live_edit_root)) base = scene_tree->root->get_node(live_edit_root); - Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); + Map<String, Set<Node *>>::Element *E = live_scene_edit_cache.find(live_edit_scene); if (!E) return; //scene not editable @@ -557,7 +557,7 @@ void LiveEditor::_node_call_func(int p_id, const StringName &p_method, VARIANT_A if (scene_tree->root->has_node(live_edit_root)) base = scene_tree->root->get_node(live_edit_root); - Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); + Map<String, Set<Node *>>::Element *E = live_scene_edit_cache.find(live_edit_scene); if (!E) return; //scene not editable @@ -630,7 +630,7 @@ void LiveEditor::_create_node_func(const NodePath &p_parent, const String &p_typ if (scene_tree->root->has_node(live_edit_root)) base = scene_tree->root->get_node(live_edit_root); - Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); + Map<String, Set<Node *>>::Element *E = live_scene_edit_cache.find(live_edit_scene); if (!E) return; //scene not editable @@ -668,7 +668,7 @@ void LiveEditor::_instance_node_func(const NodePath &p_parent, const String &p_p if (scene_tree->root->has_node(live_edit_root)) base = scene_tree->root->get_node(live_edit_root); - Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); + Map<String, Set<Node *>>::Element *E = live_scene_edit_cache.find(live_edit_scene); if (!E) return; //scene not editable @@ -701,7 +701,7 @@ void LiveEditor::_remove_node_func(const NodePath &p_at) { if (scene_tree->root->has_node(live_edit_root)) base = scene_tree->root->get_node(live_edit_root); - Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); + Map<String, Set<Node *>>::Element *E = live_scene_edit_cache.find(live_edit_scene); if (!E) return; //scene not editable @@ -732,7 +732,7 @@ void LiveEditor::_remove_and_keep_node_func(const NodePath &p_at, ObjectID p_kee if (scene_tree->root->has_node(live_edit_root)) base = scene_tree->root->get_node(live_edit_root); - Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); + Map<String, Set<Node *>>::Element *E = live_scene_edit_cache.find(live_edit_scene); if (!E) return; //scene not editable @@ -766,7 +766,7 @@ void LiveEditor::_restore_node_func(ObjectID p_id, const NodePath &p_at, int p_a if (scene_tree->root->has_node(live_edit_root)) base = scene_tree->root->get_node(live_edit_root); - Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); + Map<String, Set<Node *>>::Element *E = live_scene_edit_cache.find(live_edit_scene); if (!E) return; //scene not editable @@ -783,7 +783,7 @@ void LiveEditor::_restore_node_func(ObjectID p_id, const NodePath &p_at, int p_a continue; Node *n2 = n->get_node(p_at); - Map<Node *, Map<ObjectID, Node *> >::Element *EN = live_edit_remove_list.find(n); + Map<Node *, Map<ObjectID, Node *>>::Element *EN = live_edit_remove_list.find(n); if (!EN) continue; @@ -812,7 +812,7 @@ void LiveEditor::_duplicate_node_func(const NodePath &p_at, const String &p_new_ if (scene_tree->root->has_node(live_edit_root)) base = scene_tree->root->get_node(live_edit_root); - Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); + Map<String, Set<Node *>>::Element *E = live_scene_edit_cache.find(live_edit_scene); if (!E) return; //scene not editable @@ -845,7 +845,7 @@ void LiveEditor::_reparent_node_func(const NodePath &p_at, const NodePath &p_new if (scene_tree->root->has_node(live_edit_root)) base = scene_tree->root->get_node(live_edit_root); - Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); + Map<String, Set<Node *>>::Element *E = live_scene_edit_cache.find(live_edit_scene); if (!E) return; //scene not editable diff --git a/scene/debugger/scene_debugger.h b/scene/debugger/scene_debugger.h index afe58a5d01..e295510960 100644 --- a/scene/debugger/scene_debugger.h +++ b/scene/debugger/scene_debugger.h @@ -113,8 +113,8 @@ private: NodePath live_edit_root; String live_edit_scene; - Map<String, Set<Node *> > live_scene_edit_cache; - Map<Node *, Map<ObjectID, Node *> > live_edit_remove_list; + Map<String, Set<Node *>> live_scene_edit_cache; + Map<Node *, Map<ObjectID, Node *>> live_edit_remove_list; void _send_tree(); diff --git a/scene/gui/control.h b/scene/gui/control.h index 67e8ed0d27..15a32b8f67 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -198,10 +198,10 @@ private: NodePath focus_next; NodePath focus_prev; - HashMap<StringName, Ref<Texture2D> > icon_override; - HashMap<StringName, Ref<Shader> > shader_override; - HashMap<StringName, Ref<StyleBox> > style_override; - HashMap<StringName, Ref<Font> > font_override; + HashMap<StringName, Ref<Texture2D>> icon_override; + HashMap<StringName, Ref<Shader>> shader_override; + HashMap<StringName, Ref<StyleBox>> style_override; + HashMap<StringName, Ref<Font>> font_override; HashMap<StringName, Color> color_override; HashMap<StringName, int> constant_override; diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 409aec0ca6..dd439208af 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -330,7 +330,7 @@ private: ItemMeta *meta_hovering; Variant current_meta; - Vector<Ref<RichTextEffect> > custom_effects; + Vector<Ref<RichTextEffect>> custom_effects; void _invalidate_current_line(ItemFrame *p_frame); void _validate_line_caches(ItemFrame *p_frame); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 784a6afc7b..06691d09be 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -2529,13 +2529,11 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { String new_word = get_word_at_pos(mm->get_position()); if (new_word != highlighted_word) { - highlighted_word = new_word; - update(); + emit_signal("symbol_validate", new_word); } } else { if (highlighted_word != String()) { - highlighted_word = String(); - update(); + set_highlighted_word(String()); } } } @@ -2584,13 +2582,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { if (select_identifiers_enabled) { if (k->is_pressed() && !dragging_minimap && !dragging_selection) { - - highlighted_word = get_word_at_pos(get_local_mouse_position()); - update(); - + emit_signal("symbol_validate", get_word_at_pos(get_local_mouse_position())); } else { - highlighted_word = String(); - update(); + set_highlighted_word(String()); } } } @@ -7008,6 +7002,11 @@ void TextEdit::menu_option(int p_option) { } } +void TextEdit::set_highlighted_word(const String &new_word) { + highlighted_word = new_word; + update(); +} + void TextEdit::set_select_identifiers_on_hover(bool p_enable) { select_identifiers_enabled = p_enable; @@ -7225,6 +7224,7 @@ void TextEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("breakpoint_toggled", PropertyInfo(Variant::INT, "row"))); ADD_SIGNAL(MethodInfo("symbol_lookup", PropertyInfo(Variant::STRING, "symbol"), PropertyInfo(Variant::INT, "row"), PropertyInfo(Variant::INT, "column"))); ADD_SIGNAL(MethodInfo("info_clicked", PropertyInfo(Variant::INT, "row"), PropertyInfo(Variant::STRING, "info"))); + ADD_SIGNAL(MethodInfo("symbol_validate", PropertyInfo(Variant::STRING, "symbol"))); BIND_ENUM_CONSTANT(MENU_CUT); BIND_ENUM_CONSTANT(MENU_COPY); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 6e267f5a47..7d096f7897 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -268,7 +268,7 @@ private: } cache; Map<int, int> color_region_cache; - Map<int, Map<int, HighlighterInfo> > syntax_highlighting_cache; + Map<int, Map<int, HighlighterInfo>> syntax_highlighting_cache; struct TextOperation { @@ -585,6 +585,7 @@ public: bool is_insert_text_operation(); + void set_highlighted_word(const String &new_word); void set_text(String p_text); void insert_text_at_cursor(const String &p_text); void insert_at(const String &p_text, int at); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 57bb3b6b5e..f472de220b 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -172,7 +172,7 @@ void SceneTree::_flush_ugc() { while (unique_group_calls.size()) { - Map<UGCall, Vector<Variant> >::Element *E = unique_group_calls.front(); + Map<UGCall, Vector<Variant>>::Element *E = unique_group_calls.front(); Variant v[VARIANT_ARG_MAX]; for (int i = 0; i < E->get().size(); i++) @@ -546,11 +546,11 @@ bool SceneTree::idle(float p_time) { //go through timers - List<Ref<SceneTreeTimer> >::Element *L = timers.back(); //last element + List<Ref<SceneTreeTimer>>::Element *L = timers.back(); //last element - for (List<Ref<SceneTreeTimer> >::Element *E = timers.front(); E;) { + for (List<Ref<SceneTreeTimer>>::Element *E = timers.front(); E;) { - List<Ref<SceneTreeTimer> >::Element *N = E->next(); + List<Ref<SceneTreeTimer>>::Element *N = E->next(); if (pause && !E->get()->is_pause_mode_process()) { if (E == L) { break; //break on last, so if new timers were added during list traversal, ignore them. @@ -625,7 +625,7 @@ void SceneTree::finish() { } // cleanup timers - for (List<Ref<SceneTreeTimer> >::Element *E = timers.front(); E; E = E->next()) { + for (List<Ref<SceneTreeTimer>>::Element *E = timers.front(); E; E = E->next()) { E->get()->release_connections(); } timers.clear(); diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index 1bef0d3131..2f805d074f 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -157,7 +157,7 @@ private: List<ObjectID> delete_queue; - Map<UGCall, Vector<Variant> > unique_group_calls; + Map<UGCall, Vector<Variant>> unique_group_calls; bool ugc_locked; void _flush_ugc(); @@ -181,7 +181,7 @@ private: void _change_scene(Node *p_to); //void _call_group(uint32_t p_call_flags,const StringName& p_group,const StringName& p_function,const Variant& p_arg1,const Variant& p_arg2); - List<Ref<SceneTreeTimer> > timers; + List<Ref<SceneTreeTimer>> timers; ///network/// diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index c11b11bc71..8ef3bdd04e 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -422,7 +422,7 @@ void Viewport::_notification(int p_what) { // if no mouse event exists, create a motion one. This is necessary because objects or camera may have moved. // while this extra event is sent, it is checked if both camera and last object and last ID did not move. If nothing changed, the event is discarded to avoid flooding with unnecessary motion events every frame bool has_mouse_event = false; - for (List<Ref<InputEvent> >::Element *E = physics_picking_events.front(); E; E = E->next()) { + for (List<Ref<InputEvent>>::Element *E = physics_picking_events.front(); E; E = E->next()) { Ref<InputEventMouse> m = E->get(); if (m.is_valid()) { has_mouse_event = true; @@ -2948,12 +2948,14 @@ Control *Viewport::get_modal_stack_top() const { } String Viewport::get_configuration_warning() const { - /*if (get_parent() && !Object::cast_to<Control>(get_parent()) && !render_target) { return TTR("This viewport is not set as render target. If you intend for it to display its contents directly to the screen, make it a child of a Control so it can obtain a size. Otherwise, make it a RenderTarget and assign its internal texture to some node for display."); }*/ + if (size.x == 0 || size.y == 0) { + return TTR("Viewport size must be greater than 0 to render anything."); + } return String(); } diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 30c872b6ed..e511ce1b17 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -235,7 +235,7 @@ private: bool snap_controls_to_pixels; bool physics_object_picking; - List<Ref<InputEvent> > physics_picking_events; + List<Ref<InputEvent>> physics_picking_events; ObjectID physics_object_capture; ObjectID physics_object_over; Transform physics_last_object_transform; diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index ba1f738115..aa4c9bf225 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -1705,7 +1705,7 @@ float Animation::_cubic_interpolate(const float &p_pre_a, const float &p_a, cons } template <class T> -T Animation::_interpolate(const Vector<TKey<T> > &p_keys, float p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok) const { +T Animation::_interpolate(const Vector<TKey<T>> &p_keys, float p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok) const { int len = _find(p_keys, length) + 1; // try to find last key (there may be more past the end) diff --git a/scene/resources/animation.h b/scene/resources/animation.h index ea4f92878d..36d5df52df 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -105,7 +105,7 @@ private: struct TransformTrack : public Track { - Vector<TKey<TransformKey> > transforms; + Vector<TKey<TransformKey>> transforms; TransformTrack() { type = TYPE_TRANSFORM; } }; @@ -116,7 +116,7 @@ private: UpdateMode update_mode; bool update_on_seek; - Vector<TKey<Variant> > values; + Vector<TKey<Variant>> values; ValueTrack() { type = TYPE_VALUE; @@ -148,7 +148,7 @@ private: struct BezierTrack : public Track { - Vector<TKey<BezierKey> > values; + Vector<TKey<BezierKey>> values; BezierTrack() { type = TYPE_BEZIER; @@ -169,7 +169,7 @@ private: struct AudioTrack : public Track { - Vector<TKey<AudioKey> > values; + Vector<TKey<AudioKey>> values; AudioTrack() { type = TYPE_AUDIO; @@ -180,7 +180,7 @@ private: struct AnimationTrack : public Track { - Vector<TKey<StringName> > values; + Vector<TKey<StringName>> values; AnimationTrack() { type = TYPE_ANIMATION; @@ -216,7 +216,7 @@ private: _FORCE_INLINE_ float _cubic_interpolate(const float &p_pre_a, const float &p_a, const float &p_b, const float &p_post_b, float p_c) const; template <class T> - _FORCE_INLINE_ T _interpolate(const Vector<TKey<T> > &p_keys, float p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok) const; + _FORCE_INLINE_ T _interpolate(const Vector<TKey<T>> &p_keys, float p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok) const; template <class T> _FORCE_INLINE_ void _track_get_key_indices_in_range(const Vector<T> &p_array, float from_time, float to_time, List<int> *p_indices) const; diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp index ed25729c40..a68b750b31 100644 --- a/scene/resources/audio_stream_sample.cpp +++ b/scene/resources/audio_stream_sample.cpp @@ -258,7 +258,7 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in float srate = base->mix_rate; srate *= p_rate_scale; float fincrement = srate / base_rate; - int32_t increment = int32_t(fincrement * MIX_FRAC_LEN); + int32_t increment = int32_t(MAX(fincrement * MIX_FRAC_LEN, 1)); increment *= sign; //looping diff --git a/scene/resources/bit_map.cpp b/scene/resources/bit_map.cpp index 6730f86e0c..d45f36dfd1 100644 --- a/scene/resources/bit_map.cpp +++ b/scene/resources/bit_map.cpp @@ -493,7 +493,7 @@ static void fill_bits(const BitMap *p_src, Ref<BitMap> &p_map, const Point2i &p_ print_verbose("BitMap: Max stack size: " + itos(stack.size())); } -Vector<Vector<Vector2> > BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, float p_epsilon) const { +Vector<Vector<Vector2>> BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, float p_epsilon) const { Rect2i r = Rect2i(0, 0, width, height).clip(p_rect); print_verbose("BitMap: Rect: " + r); @@ -503,7 +503,7 @@ Vector<Vector<Vector2> > BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, fl fill.instance(); fill->create(get_size()); - Vector<Vector<Vector2> > polygons; + Vector<Vector<Vector2>> polygons; for (int i = r.position.y; i < r.position.y + r.size.height; i++) { for (int j = r.position.x; j < r.position.x + r.size.width; j++) { if (!fill->get_bit(Point2(j, i)) && get_bit(Point2(j, i))) { @@ -591,7 +591,7 @@ void BitMap::shrink_mask(int p_pixels, const Rect2 &p_rect) { Array BitMap::_opaque_to_polygons_bind(const Rect2 &p_rect, float p_epsilon) const { - Vector<Vector<Vector2> > result = clip_opaque_to_polygons(p_rect, p_epsilon); + Vector<Vector<Vector2>> result = clip_opaque_to_polygons(p_rect, p_epsilon); // Convert result to bindable types diff --git a/scene/resources/bit_map.h b/scene/resources/bit_map.h index ed332dffa4..05313a0cff 100644 --- a/scene/resources/bit_map.h +++ b/scene/resources/bit_map.h @@ -72,7 +72,7 @@ public: void blit(const Vector2 &p_pos, const Ref<BitMap> &p_bitmap); Ref<Image> convert_to_image() const; - Vector<Vector<Vector2> > clip_opaque_to_polygons(const Rect2 &p_rect, float p_epsilon = 2.0) const; + Vector<Vector<Vector2>> clip_opaque_to_polygons(const Rect2 &p_rect, float p_epsilon = 2.0) const; BitMap(); }; diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index a68eb77378..d19eae0d4f 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -941,7 +941,7 @@ PackedVector2Array Curve2D::tessellate(int p_max_stages, float p_tolerance) cons if (points.size() == 0) { return tess; } - Vector<Map<float, Vector2> > midpoints; + Vector<Map<float, Vector2>> midpoints; midpoints.resize(points.size() - 1); @@ -1615,7 +1615,7 @@ PackedVector3Array Curve3D::tessellate(int p_max_stages, float p_tolerance) cons if (points.size() == 0) { return tess; } - Vector<Map<float, Vector3> > midpoints; + Vector<Map<float, Vector3>> midpoints; midpoints.resize(points.size() - 1); diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 04bc95ade6..9f5b49c4c3 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -38,7 +38,7 @@ #include "font_hidpi.inc" #include "font_lodpi.inc" -typedef Map<const void *, Ref<ImageTexture> > TexCacheMap; +typedef Map<const void *, Ref<ImageTexture>> TexCacheMap; static TexCacheMap *tex_cache; static float scale = 1; diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index ebd5b02dbc..410c4990a2 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -115,7 +115,7 @@ DynamicFontData::~DynamicFontData() { } //////////////////// -HashMap<String, Vector<uint8_t> > DynamicFontAtSize::_fontdata; +HashMap<String, Vector<uint8_t>> DynamicFontAtSize::_fontdata; Error DynamicFontAtSize::_load() { @@ -243,7 +243,7 @@ float DynamicFontAtSize::get_descent() const { return descent; } -const Pair<const DynamicFontAtSize::Character *, DynamicFontAtSize *> DynamicFontAtSize::_find_char_with_font(CharType p_char, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks) const { +const Pair<const DynamicFontAtSize::Character *, DynamicFontAtSize *> DynamicFontAtSize::_find_char_with_font(CharType p_char, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const { const Character *chr = char_map.getptr(p_char); ERR_FAIL_COND_V(!chr, (Pair<const Character *, DynamicFontAtSize *>(NULL, NULL))); @@ -275,7 +275,7 @@ const Pair<const DynamicFontAtSize::Character *, DynamicFontAtSize *> DynamicFon return Pair<const Character *, DynamicFontAtSize *>(chr, const_cast<DynamicFontAtSize *>(this)); } -Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks) const { +Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const { if (!valid) return Size2(1, 1); @@ -294,7 +294,7 @@ Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const V return ret; } -float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks, bool p_advance_only, bool p_outline) const { +float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks, bool p_advance_only, bool p_outline) const { if (!valid) return 0; @@ -850,7 +850,7 @@ float DynamicFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_ if (!font_at_size.is_valid()) return 0; - const Vector<Ref<DynamicFontAtSize> > &fallbacks = p_outline && outline_cache_id.outline_size > 0 ? fallback_outline_data_at_size : fallback_data_at_size; + const Vector<Ref<DynamicFontAtSize>> &fallbacks = p_outline && outline_cache_id.outline_size > 0 ? fallback_outline_data_at_size : fallback_data_at_size; Color color = p_outline && outline_cache_id.outline_size > 0 ? p_modulate * outline_color : p_modulate; // If requested outline draw, but no outline is present, simply return advance without drawing anything @@ -1025,7 +1025,7 @@ void DynamicFont::finish_dynamic_fonts() { void DynamicFont::update_oversampling() { - Vector<Ref<DynamicFont> > changed; + Vector<Ref<DynamicFont>> changed; { MutexLock lock(dynamic_font_mutex); diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h index c10f1e6681..88b1df039e 100644 --- a/scene/resources/dynamic_font.h +++ b/scene/resources/dynamic_font.h @@ -161,7 +161,7 @@ class DynamicFontAtSize : public Reference { int y; }; - const Pair<const Character *, DynamicFontAtSize *> _find_char_with_font(CharType p_char, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks) const; + const Pair<const Character *, DynamicFontAtSize *> _find_char_with_font(CharType p_char, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const; Character _make_outline_char(CharType p_char); TexturePosition _find_texture_pos_for_glyph(int p_color_size, Image::Format p_image_format, int p_width, int p_height); Character _bitmap_to_character(FT_Bitmap bitmap, int yofs, int xofs, float advance); @@ -177,7 +177,7 @@ class DynamicFontAtSize : public Reference { Ref<DynamicFontData> font; DynamicFontData::CacheID id; - static HashMap<String, Vector<uint8_t> > _fontdata; + static HashMap<String, Vector<uint8_t>> _fontdata; Error _load(); public: @@ -188,9 +188,9 @@ public: float get_ascent() const; float get_descent() const; - Size2 get_char_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks) const; + Size2 get_char_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const; - float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks, bool p_advance_only = false, bool p_outline = false) const; + float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks, bool p_advance_only = false, bool p_outline = false) const; void set_texture_flags(uint32_t p_flags); void update_oversampling(); @@ -218,9 +218,9 @@ private: Ref<DynamicFontAtSize> data_at_size; Ref<DynamicFontAtSize> outline_data_at_size; - Vector<Ref<DynamicFontData> > fallbacks; - Vector<Ref<DynamicFontAtSize> > fallback_data_at_size; - Vector<Ref<DynamicFontAtSize> > fallback_outline_data_at_size; + Vector<Ref<DynamicFontData>> fallbacks; + Vector<Ref<DynamicFontAtSize>> fallback_data_at_size; + Vector<Ref<DynamicFontAtSize>> fallback_outline_data_at_size; DynamicFontData::CacheID cache_id; DynamicFontData::CacheID outline_cache_id; diff --git a/scene/resources/font.h b/scene/resources/font.h index 85b295b5f8..076532f390 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -108,7 +108,7 @@ class BitmapFont : public Font { GDCLASS(BitmapFont, Font); RES_BASE_EXTENSION("font"); - Vector<Ref<Texture2D> > textures; + Vector<Ref<Texture2D>> textures; public: struct Character { diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 5e032c41bf..f93b7ced98 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -541,15 +541,15 @@ void Mesh::clear_cache() const { debug_lines.clear(); } -Vector<Ref<Shape> > Mesh::convex_decompose() const { +Vector<Ref<Shape>> Mesh::convex_decompose() const { - ERR_FAIL_COND_V(!convex_composition_function, Vector<Ref<Shape> >()); + ERR_FAIL_COND_V(!convex_composition_function, Vector<Ref<Shape>>()); const Vector<Face3> faces = get_faces(); - Vector<Vector<Face3> > decomposed = convex_composition_function(faces); + Vector<Vector<Face3>> decomposed = convex_composition_function(faces); - Vector<Ref<Shape> > ret; + Vector<Ref<Shape>> ret; for (int i = 0; i < decomposed.size(); i++) { Set<Vector3> points; @@ -788,7 +788,7 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { if (d.has("index_count")) index_count = d["index_count"]; - Vector<Vector<uint8_t> > blend_shapes; + Vector<Vector<uint8_t>> blend_shapes; if (d.has("blend_shape_data")) { Array blend_shape_data = d["blend_shape_data"]; @@ -910,7 +910,7 @@ void ArrayMesh::_create_if_empty() const { void ArrayMesh::_set_surfaces(const Array &p_surfaces) { Vector<VS::SurfaceData> surface_data; - Vector<Ref<Material> > surface_materials; + Vector<Ref<Material>> surface_materials; Vector<String> surface_names; Vector<bool> surface_2d; @@ -1102,7 +1102,7 @@ void ArrayMesh::_recompute_aabb() { #ifndef _MSC_VER #warning need to add binding to add_surface using future MeshSurfaceData object #endif -void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t> > &p_blend_shapes, const Vector<AABB> &p_bone_aabb, const Vector<VS::SurfaceData::LOD> &p_lods) { +void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t>> &p_blend_shapes, const Vector<AABB> &p_bone_aabb, const Vector<VS::SurfaceData::LOD> &p_lods) { _create_if_empty(); @@ -1341,7 +1341,7 @@ void ArrayMesh::regen_normalmaps() { if (surfaces.size() == 0) { return; } - Vector<Ref<SurfaceTool> > surfs; + Vector<Ref<SurfaceTool>> surfs; for (int i = 0; i < get_surface_count(); i++) { Ref<SurfaceTool> st = memnew(SurfaceTool); @@ -1379,7 +1379,7 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe Vector<int> indices; Vector<int> face_materials; Vector<float> uv; - Vector<Pair<int, int> > uv_index; + Vector<Pair<int, int>> uv_index; Vector<ArrayMeshLightmapSurface> surfaces; for (int i = 0; i < get_surface_count(); i++) { @@ -1472,7 +1472,7 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe clear_surfaces(); //create surfacetools for each surface.. - Vector<Ref<SurfaceTool> > surfaces_tools; + Vector<Ref<SurfaceTool>> surfaces_tools; for (int i = 0; i < surfaces.size(); i++) { Ref<SurfaceTool> st; diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 0e356c16a6..e0cc214301 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -142,11 +142,11 @@ public: Size2 get_lightmap_size_hint() const; void clear_cache() const; - typedef Vector<Vector<Face3> > (*ConvexDecompositionFunc)(const Vector<Face3> &); + typedef Vector<Vector<Face3>> (*ConvexDecompositionFunc)(const Vector<Face3> &); static ConvexDecompositionFunc convex_composition_function; - Vector<Ref<Shape> > convex_decompose() const; + Vector<Ref<Shape>> convex_decompose() const; Mesh(); }; @@ -193,7 +193,7 @@ protected: public: void add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_flags = ARRAY_COMPRESS_DEFAULT); - void add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t> > &p_blend_shapes = Vector<Vector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>(), const Vector<VS::SurfaceData::LOD> &p_lods = Vector<VS::SurfaceData::LOD>()); + void add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t>> &p_blend_shapes = Vector<Vector<uint8_t>>(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>(), const Vector<VS::SurfaceData::LOD> &p_lods = Vector<VS::SurfaceData::LOD>()); Array surface_get_arrays(int p_surface) const; Array surface_get_blend_shape_arrays(int p_surface) const; diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 0538f679cc..7059682904 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -82,7 +82,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const { bool gen_node_path_cache = p_edit_state != GEN_EDIT_STATE_DISABLED && node_path_cache.empty(); - Map<Ref<Resource>, Ref<Resource> > resources_local_to_scene; + Map<Ref<Resource>, Ref<Resource>> resources_local_to_scene; for (int i = 0; i < nc; i++) { @@ -201,7 +201,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const { //https://github.com/godotengine/godot/issues/2958 //store old state - List<Pair<StringName, Variant> > old_state; + List<Pair<StringName, Variant>> old_state; if (node->get_script_instance()) { node->get_script_instance()->get_property_state(old_state); } @@ -209,7 +209,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const { node->set(snames[nprops[j].name], props[nprops[j].value], &valid); //restore old state for new script, if exists - for (List<Pair<StringName, Variant> >::Element *E = old_state.front(); E; E = E->next()) { + for (List<Pair<StringName, Variant>>::Element *E = old_state.front(); E; E = E->next()) { node->set(E->get().first, E->get().second); } } else { @@ -222,7 +222,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const { if (res.is_valid()) { if (res->is_local_to_scene()) { - Map<Ref<Resource>, Ref<Resource> >::Element *E = resources_local_to_scene.find(res); + Map<Ref<Resource>, Ref<Resource>>::Element *E = resources_local_to_scene.find(res); if (E) { value = E->get(); @@ -302,7 +302,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const { } } - for (Map<Ref<Resource>, Ref<Resource> >::Element *E = resources_local_to_scene.front(); E; E = E->next()) { + for (Map<Ref<Resource>, Ref<Resource>>::Element *E = resources_local_to_scene.front(); E; E = E->next()) { E->get()->setup_local_to_scene(); } diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 00fc016ca1..959ee214a2 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -150,7 +150,7 @@ Array PrimitiveMesh::surface_get_blend_shape_arrays(int p_surface) const { uint32_t PrimitiveMesh::surface_get_format(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, 1, 0); - return VS::ARRAY_COMPRESS_DEFAULT; + return VS::ARRAY_FORMAT_VERTEX | VS::ARRAY_FORMAT_NORMAL | VS::ARRAY_FORMAT_TANGENT | VS::ARRAY_FORMAT_TEX_UV | VS::ARRAY_FORMAT_INDEX | VS::ARRAY_COMPRESS_DEFAULT; } Mesh::PrimitiveType PrimitiveMesh::surface_get_primitive_type(int p_idx) const { diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 8f76c0165f..e61a1e6880 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -121,7 +121,7 @@ Ref<Texture2D> Shader::get_default_texture_param(const StringName &p_param) cons void Shader::get_default_texture_param_list(List<StringName> *r_textures) const { - for (const Map<StringName, Ref<Texture2D> >::Element *E = default_textures.front(); E; E = E->next()) { + for (const Map<StringName, Ref<Texture2D>>::Element *E = default_textures.front(); E; E = E->next()) { r_textures->push_back(E->key()); } diff --git a/scene/resources/shader.h b/scene/resources/shader.h index 5050632dd5..84908852da 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -59,7 +59,7 @@ private: // conversion fast and save memory. mutable bool params_cache_dirty; mutable Map<StringName, StringName> params_cache; //map a shader param to a material param.. - Map<StringName, Ref<Texture2D> > default_textures; + Map<StringName, Ref<Texture2D>> default_textures; virtual void _update_shader() const; //used for visual shader protected: diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index cb827c4b0b..1c5b2abad2 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -370,7 +370,7 @@ Ref<Image> StreamTexture::load_image_from_file(FileAccess *f, int p_size_limit) int sh = h; //mipmaps need to be read independently, they will be later combined - Vector<Ref<Image> > mipmap_images; + Vector<Ref<Image>> mipmap_images; int total_size = 0; bool first = true; @@ -1899,7 +1899,7 @@ uint32_t TextureLayered::get_layers() const { } Error TextureLayered::_create_from_images(const Array &p_images) { - Vector<Ref<Image> > images; + Vector<Ref<Image>> images; for (int i = 0; i < p_images.size(); i++) { Ref<Image> img = p_images[i]; ERR_FAIL_COND_V(img.is_null(), ERR_INVALID_PARAMETER); @@ -1917,7 +1917,7 @@ Array TextureLayered::_get_images() const { return images; } -Error TextureLayered::create_from_images(Vector<Ref<Image> > p_images) { +Error TextureLayered::create_from_images(Vector<Ref<Image>> p_images) { int new_layers = p_images.size(); ERR_FAIL_COND_V(new_layers == 0, ERR_INVALID_PARAMETER); @@ -2077,7 +2077,7 @@ RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String Image::Format format = Image::Format(f->get_32()); uint32_t compression = f->get_32(); // 0 - lossless (PNG), 1 - vram, 2 - uncompressed - Vector<Ref<Image> > images; + Vector<Ref<Image>> images; for (int layer = 0; layer < td; layer++) { Ref<Image> image; @@ -2087,7 +2087,7 @@ RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String //look for a PNG file inside int mipmaps = f->get_32(); - Vector<Ref<Image> > mipmap_images; + Vector<Ref<Image>> mipmap_images; for (int i = 0; i < mipmaps; i++) { uint32_t size = f->get_32(); diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 237c02a8cd..1fb8742cec 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -376,7 +376,7 @@ public: uint32_t get_layers() const; bool has_mipmaps() const; - Error create_from_images(Vector<Ref<Image> > p_images); + Error create_from_images(Vector<Ref<Image>> p_images); void update_layer(const Ref<Image> &p_image, int p_layer); Ref<Image> get_layer_data(int p_layer) const; diff --git a/scene/resources/theme.h b/scene/resources/theme.h index 3d01f71ea0..d6d724e3f7 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -45,12 +45,12 @@ class Theme : public Resource { void _emit_theme_changed(); - HashMap<StringName, HashMap<StringName, Ref<Texture2D> > > icon_map; - HashMap<StringName, HashMap<StringName, Ref<StyleBox> > > style_map; - HashMap<StringName, HashMap<StringName, Ref<Font> > > font_map; - HashMap<StringName, HashMap<StringName, Ref<Shader> > > shader_map; - HashMap<StringName, HashMap<StringName, Color> > color_map; - HashMap<StringName, HashMap<StringName, int> > constant_map; + HashMap<StringName, HashMap<StringName, Ref<Texture2D>>> icon_map; + HashMap<StringName, HashMap<StringName, Ref<StyleBox>>> style_map; + HashMap<StringName, HashMap<StringName, Ref<Font>>> font_map; + HashMap<StringName, HashMap<StringName, Ref<Shader>>> shader_map; + HashMap<StringName, HashMap<StringName, Color>> color_map; + HashMap<StringName, HashMap<StringName, int>> constant_map; Vector<String> _get_icon_list(const String &p_type) const; Vector<String> _get_stylebox_list(const String &p_type) const; diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index f42b56bc83..b312aa054c 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -252,14 +252,14 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const { r_ret = p; } else if (what == "occluder_map") { Array p; - for (Map<Vector2, Ref<OccluderPolygon2D> >::Element *E = tile_map[id].autotile_data.occluder_map.front(); E; E = E->next()) { + for (Map<Vector2, Ref<OccluderPolygon2D>>::Element *E = tile_map[id].autotile_data.occluder_map.front(); E; E = E->next()) { p.push_back(E->key()); p.push_back(E->value()); } r_ret = p; } else if (what == "navpoly_map") { Array p; - for (Map<Vector2, Ref<NavigationPolygon> >::Element *E = tile_map[id].autotile_data.navpoly_map.front(); E; E = E->next()) { + for (Map<Vector2, Ref<NavigationPolygon>>::Element *E = tile_map[id].autotile_data.navpoly_map.front(); E; E = E->next()) { p.push_back(E->key()); p.push_back(E->value()); } @@ -903,9 +903,9 @@ Ref<NavigationPolygon> TileSet::tile_get_navigation_polygon(int p_id) const { return tile_map[p_id].navigation_polygon; } -const Map<Vector2, Ref<OccluderPolygon2D> > &TileSet::autotile_get_light_oclusion_map(int p_id) const { +const Map<Vector2, Ref<OccluderPolygon2D>> &TileSet::autotile_get_light_oclusion_map(int p_id) const { - static Map<Vector2, Ref<OccluderPolygon2D> > dummy; + static Map<Vector2, Ref<OccluderPolygon2D>> dummy; ERR_FAIL_COND_V(!tile_map.has(p_id), dummy); return tile_map[p_id].autotile_data.occluder_map; } @@ -932,9 +932,9 @@ Ref<NavigationPolygon> TileSet::autotile_get_navigation_polygon(int p_id, const } } -const Map<Vector2, Ref<NavigationPolygon> > &TileSet::autotile_get_navigation_map(int p_id) const { +const Map<Vector2, Ref<NavigationPolygon>> &TileSet::autotile_get_navigation_map(int p_id) const { - static Map<Vector2, Ref<NavigationPolygon> > dummy; + static Map<Vector2, Ref<NavigationPolygon>> dummy; ERR_FAIL_COND_V(!tile_map.has(p_id), dummy); return tile_map[p_id].autotile_data.navpoly_map; } @@ -1077,7 +1077,7 @@ void TileSet::_decompose_convex_shape(Ref<Shape2D> p_shape) { Ref<ConvexPolygonShape2D> convex = p_shape; if (!convex.is_valid()) return; - Vector<Vector<Vector2> > decomp = Geometry::decompose_polygon_in_convex(convex->get_points()); + Vector<Vector<Vector2>> decomp = Geometry::decompose_polygon_in_convex(convex->get_points()); if (decomp.size() > 1) { Array sub_shapes; for (int i = 0; i < decomp.size(); i++) { diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index 8b540982a4..3c964ec667 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -97,8 +97,8 @@ public: int spacing; Vector2 icon_coord; Map<Vector2, uint32_t> flags; - Map<Vector2, Ref<OccluderPolygon2D> > occluder_map; - Map<Vector2, Ref<NavigationPolygon> > navpoly_map; + Map<Vector2, Ref<OccluderPolygon2D>> occluder_map; + Map<Vector2, Ref<NavigationPolygon>> navpoly_map; Map<Vector2, int> priority_map; Map<Vector2, int> z_index_map; @@ -233,7 +233,7 @@ public: void autotile_set_light_occluder(int p_id, const Ref<OccluderPolygon2D> &p_light_occluder, const Vector2 &p_coord); Ref<OccluderPolygon2D> autotile_get_light_occluder(int p_id, const Vector2 &p_coord) const; - const Map<Vector2, Ref<OccluderPolygon2D> > &autotile_get_light_oclusion_map(int p_id) const; + const Map<Vector2, Ref<OccluderPolygon2D>> &autotile_get_light_oclusion_map(int p_id) const; void tile_set_navigation_polygon_offset(int p_id, const Vector2 &p_offset); Vector2 tile_get_navigation_polygon_offset(int p_id) const; @@ -243,7 +243,7 @@ public: void autotile_set_navigation_polygon(int p_id, const Ref<NavigationPolygon> &p_navigation_polygon, const Vector2 &p_coord); Ref<NavigationPolygon> autotile_get_navigation_polygon(int p_id, const Vector2 &p_coord) const; - const Map<Vector2, Ref<NavigationPolygon> > &autotile_get_navigation_map(int p_id) const; + const Map<Vector2, Ref<NavigationPolygon>> &autotile_get_navigation_map(int p_id) const; void tile_set_z_index(int p_id, int p_z_index); int tile_get_z_index(int p_id) const; diff --git a/servers/arvr_server.h b/servers/arvr_server.h index af1d2ba39f..ab2f0d721b 100644 --- a/servers/arvr_server.h +++ b/servers/arvr_server.h @@ -76,7 +76,7 @@ public: }; private: - Vector<Ref<ARVRInterface> > interfaces; + Vector<Ref<ARVRInterface>> interfaces; Vector<ARVRPositionalTracker *> trackers; Ref<ARVRInterface> primary_interface; /* we'll identify one interface as primary, this will be used by our viewports */ diff --git a/servers/audio/effects/audio_effect_spectrum_analyzer.h b/servers/audio/effects/audio_effect_spectrum_analyzer.h index 8e735b8b50..a110f7a8e5 100644 --- a/servers/audio/effects/audio_effect_spectrum_analyzer.h +++ b/servers/audio/effects/audio_effect_spectrum_analyzer.h @@ -48,7 +48,7 @@ private: friend class AudioEffectSpectrumAnalyzer; Ref<AudioEffectSpectrumAnalyzer> base; - Vector<Vector<AudioFrame> > fft_history; + Vector<Vector<AudioFrame>> fft_history; Vector<float> temporal_fft; int temporal_fft_pos; int fft_size; diff --git a/servers/audio_server.h b/servers/audio_server.h index cc0c9d1112..8df0172750 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -198,7 +198,7 @@ private: bool active; AudioFrame peak_volume; Vector<AudioFrame> buffer; - Vector<Ref<AudioEffectInstance> > effect_instances; + Vector<Ref<AudioEffectInstance>> effect_instances; uint64_t last_mix_with_audio; Channel() { last_mix_with_audio = 0; @@ -224,7 +224,7 @@ private: int index_cache; }; - Vector<Vector<AudioFrame> > temp_buffer; //temp_buffer for each level + Vector<Vector<AudioFrame>> temp_buffer; //temp_buffer for each level Vector<Bus *> buses; Map<StringName, Bus *> bus_map; diff --git a/servers/camera_server.h b/servers/camera_server.h index c4b3d9f5c9..b268553fe5 100644 --- a/servers/camera_server.h +++ b/servers/camera_server.h @@ -65,7 +65,7 @@ private: protected: static CreateFunc create_func; - Vector<Ref<CameraFeed> > feeds; + Vector<Ref<CameraFeed>> feeds; static CameraServer *singleton; diff --git a/servers/navigation_2d_server.h b/servers/navigation_2d_server.h index 955b0c3726..7b0b9fbb01 100644 --- a/servers/navigation_2d_server.h +++ b/servers/navigation_2d_server.h @@ -49,7 +49,7 @@ protected: static void _bind_methods(); public: - /// Thread safe, can be used accross many threads. + /// Thread safe, can be used across many threads. static const Navigation2DServer *get_singleton() { return singleton; } /// MUST be used in single thread! diff --git a/servers/navigation_server.h b/servers/navigation_server.h index 7c9b6ba595..546e543db3 100644 --- a/servers/navigation_server.h +++ b/servers/navigation_server.h @@ -54,7 +54,7 @@ protected: static void _bind_methods(); public: - /// Thread safe, can be used accross many threads. + /// Thread safe, can be used across many threads. static const NavigationServer *get_singleton(); /// MUST be used in single thread! diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 0a55c78133..2670a750d7 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -178,7 +178,7 @@ public: } void clean_up_dependencies() { - List<Pair<InstanceDependency *, Map<InstanceBase *, uint32_t>::Element *> > to_clean_up; + List<Pair<InstanceDependency *, Map<InstanceBase *, uint32_t>::Element *>> to_clean_up; for (Set<InstanceDependency *>::Element *E = dependencies.front(); E; E = E->next()) { InstanceDependency *dep = E->get(); Map<InstanceBase *, uint32_t>::Element *F = dep->instances.find(this); @@ -277,8 +277,8 @@ public: /* TEXTURE API */ virtual RID texture_2d_create(const Ref<Image> &p_image) = 0; - virtual RID texture_2d_layered_create(const Vector<Ref<Image> > &p_layers, VS::TextureLayeredType p_layered_type) = 0; - virtual RID texture_3d_create(const Vector<Ref<Image> > &p_slices) = 0; //all slices, then all the mipmaps, must be coherent + virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, VS::TextureLayeredType p_layered_type) = 0; + virtual RID texture_3d_create(const Vector<Ref<Image>> &p_slices) = 0; //all slices, then all the mipmaps, must be coherent virtual RID texture_proxy_create(RID p_base) = 0; //all slices, then all the mipmaps, must be coherent virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; //mostly used for video and streaming diff --git a/servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp index 78fff0c381..38b1e3b3a6 100644 --- a/servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp @@ -2242,14 +2242,14 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) { //non light variants variants.push_back(""); //none by default is first variant variants.push_back("#define USE_NINEPATCH\n"); //ninepatch is the second variant - variants.push_back("#define USE_PRIMITIVE\n"); //primitve is the third + variants.push_back("#define USE_PRIMITIVE\n"); //primitive is the third variants.push_back("#define USE_PRIMITIVE\n#define USE_POINT_SIZE\n"); //points need point size variants.push_back("#define USE_ATTRIBUTES\n"); // attributes for vertex arrays variants.push_back("#define USE_ATTRIBUTES\n#define USE_POINT_SIZE\n"); //attributes with point size //light variants variants.push_back("#define USE_LIGHTING\n"); //none by default is first variant variants.push_back("#define USE_LIGHTING\n#define USE_NINEPATCH\n"); //ninepatch is the second variant - variants.push_back("#define USE_LIGHTING\n#define USE_PRIMITIVE\n"); //primitve is the third + variants.push_back("#define USE_LIGHTING\n#define USE_PRIMITIVE\n"); //primitive is the third variants.push_back("#define USE_LIGHTING\n#define USE_PRIMITIVE\n#define USE_POINT_SIZE\n"); //points need point size variants.push_back("#define USE_LIGHTING\n#define USE_ATTRIBUTES\n"); // attributes for vertex arrays variants.push_back("#define USE_LIGHTING\n#define USE_ATTRIBUTES\n#define USE_POINT_SIZE\n"); //attributes with point size diff --git a/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp index 52cefa7511..b8d7a9dcf4 100644 --- a/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp @@ -585,7 +585,7 @@ RID RasterizerStorageRD::texture_2d_create(const Ref<Image> &p_image) { rd_view.swizzle_a = ret_format.swizzle_a; } Vector<uint8_t> data = image->get_data(); //use image data - Vector<Vector<uint8_t> > data_slices; + Vector<Vector<uint8_t>> data_slices; data_slices.push_back(data); texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices); ERR_FAIL_COND_V(texture.rd_texture.is_null(), RID()); @@ -608,11 +608,11 @@ RID RasterizerStorageRD::texture_2d_create(const Ref<Image> &p_image) { return texture_owner.make_rid(texture); } -RID RasterizerStorageRD::texture_2d_layered_create(const Vector<Ref<Image> > &p_layers, VS::TextureLayeredType p_layered_type) { +RID RasterizerStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, VS::TextureLayeredType p_layered_type) { return RID(); } -RID RasterizerStorageRD::texture_3d_create(const Vector<Ref<Image> > &p_slices) { +RID RasterizerStorageRD::texture_3d_create(const Vector<Ref<Image>> &p_slices) { return RID(); } @@ -3597,7 +3597,7 @@ void RasterizerStorageRD::gi_probe_allocate(RID p_gi_probe, const Transform &p_t tf.depth = gi_probe->octree_size.z; tf.type = RD::TEXTURE_TYPE_3D; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; - Vector<Vector<uint8_t> > s; + Vector<Vector<uint8_t>> s; s.push_back(p_distance_field); gi_probe->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView(), s); } @@ -3938,7 +3938,7 @@ void RasterizerStorageRD::_update_render_target(RenderTarget *rt) { if (rt->size.width == 0 || rt->size.height == 0) { return; } - //until we implement suport for HDR monitors (and render target is attached to screen), this is enough. + //until we implement support for HDR monitors (and render target is attached to screen), this is enough. rt->color_format = RD::DATA_FORMAT_R8G8B8A8_UNORM; rt->color_format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; rt->image_format = rt->flags[RENDER_TARGET_TRANSPARENT] ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8; @@ -4473,7 +4473,7 @@ RasterizerStorageRD::RasterizerStorageRD() { } { - Vector<Vector<uint8_t> > vpv; + Vector<Vector<uint8_t>> vpv; vpv.push_back(pv); default_rd_textures[DEFAULT_RD_TEXTURE_WHITE] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); } @@ -4486,7 +4486,7 @@ RasterizerStorageRD::RasterizerStorageRD() { } { - Vector<Vector<uint8_t> > vpv; + Vector<Vector<uint8_t>> vpv; vpv.push_back(pv); default_rd_textures[DEFAULT_RD_TEXTURE_BLACK] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); } @@ -4499,7 +4499,7 @@ RasterizerStorageRD::RasterizerStorageRD() { } { - Vector<Vector<uint8_t> > vpv; + Vector<Vector<uint8_t>> vpv; vpv.push_back(pv); default_rd_textures[DEFAULT_RD_TEXTURE_NORMAL] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); } @@ -4512,7 +4512,7 @@ RasterizerStorageRD::RasterizerStorageRD() { } { - Vector<Vector<uint8_t> > vpv; + Vector<Vector<uint8_t>> vpv; vpv.push_back(pv); default_rd_textures[DEFAULT_RD_TEXTURE_ANISO] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); } @@ -4547,7 +4547,7 @@ RasterizerStorageRD::RasterizerStorageRD() { } { - Vector<Vector<uint8_t> > vpv; + Vector<Vector<uint8_t>> vpv; for (int i = 0; i < 6; i++) { vpv.push_back(pv); } @@ -4575,7 +4575,7 @@ RasterizerStorageRD::RasterizerStorageRD() { } { - Vector<Vector<uint8_t> > vpv; + Vector<Vector<uint8_t>> vpv; for (int i = 0; i < 6; i++) { vpv.push_back(pv); } @@ -4603,7 +4603,7 @@ RasterizerStorageRD::RasterizerStorageRD() { } { - Vector<Vector<uint8_t> > vpv; + Vector<Vector<uint8_t>> vpv; vpv.push_back(pv); default_rd_textures[DEFAULT_RD_TEXTURE_3D_WHITE] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); } diff --git a/servers/visual/rasterizer_rd/rasterizer_storage_rd.h b/servers/visual/rasterizer_rd/rasterizer_storage_rd.h index 48097ffaac..9bc4beab6e 100644 --- a/servers/visual/rasterizer_rd/rasterizer_storage_rd.h +++ b/servers/visual/rasterizer_rd/rasterizer_storage_rd.h @@ -497,8 +497,8 @@ public: /* TEXTURE API */ virtual RID texture_2d_create(const Ref<Image> &p_image); - virtual RID texture_2d_layered_create(const Vector<Ref<Image> > &p_layers, VS::TextureLayeredType p_layered_type); - virtual RID texture_3d_create(const Vector<Ref<Image> > &p_slices); //all slices, then all the mipmaps, must be coherent + virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, VS::TextureLayeredType p_layered_type); + virtual RID texture_3d_create(const Vector<Ref<Image>> &p_slices); //all slices, then all the mipmaps, must be coherent virtual RID texture_proxy_create(RID p_base); virtual void _texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate); diff --git a/servers/visual/rasterizer_rd/shader_compiler_rd.h b/servers/visual/rasterizer_rd/shader_compiler_rd.h index c267c2b6d8..95e1f0aa23 100644 --- a/servers/visual/rasterizer_rd/shader_compiler_rd.h +++ b/servers/visual/rasterizer_rd/shader_compiler_rd.h @@ -40,7 +40,7 @@ class ShaderCompilerRD { public: struct IdentifierActions { - Map<StringName, Pair<int *, int> > render_mode_values; + Map<StringName, Pair<int *, int>> render_mode_values; Map<StringName, bool *> render_mode_flags; Map<StringName, bool *> usage_flag_pointers; Map<StringName, bool *> write_flag_pointers; diff --git a/servers/visual/rasterizer_rd/shaders/canvas.glsl b/servers/visual/rasterizer_rd/shaders/canvas.glsl index 57e9451e48..28135fce31 100644 --- a/servers/visual/rasterizer_rd/shaders/canvas.glsl +++ b/servers/visual/rasterizer_rd/shaders/canvas.glsl @@ -416,7 +416,7 @@ FRAGMENT_SHADER_CODE vec4 base_color = color; if (bool(draw_data.flags & FLAGS_USING_LIGHT_MASK)) { - color = vec4(0.0); //inivisible by default due to using light mask + color = vec4(0.0); //invisible by default due to using light mask } color *= canvas_data.canvas_modulation; diff --git a/servers/visual/rendering_device.h b/servers/visual/rendering_device.h index c3b937d5e2..ed55afd961 100644 --- a/servers/visual/rendering_device.h +++ b/servers/visual/rendering_device.h @@ -407,7 +407,7 @@ public: } }; - virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<Vector<uint8_t> > &p_data = Vector<Vector<uint8_t> >()) = 0; + virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<Vector<uint8_t>> &p_data = Vector<Vector<uint8_t>>()) = 0; virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture) = 0; enum TextureSliceType { @@ -418,7 +418,7 @@ public: virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D) = 0; - virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, bool p_sync_with_draw = false) = 0; //this function can be used from any thread and it takes effect at the begining of the frame, unless sync with draw is used, which is used to mix updates with draw calls + virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, bool p_sync_with_draw = false) = 0; //this function can be used from any thread and it takes effect at the beginning of the frame, unless sync with draw is used, which is used to mix updates with draw calls virtual Vector<uint8_t> texture_get_data(RID p_texture, uint32_t p_layer) = 0; // CPU textures will return immediately, while GPU textures will most likely force a flush virtual bool texture_is_format_supported_for_usage(DataFormat p_format, uint32_t p_usage) const = 0; @@ -621,7 +621,7 @@ public: virtual RID uniform_set_create(const Vector<Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set) = 0; virtual bool uniform_set_is_valid(RID p_uniform_set) = 0; - virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, bool p_sync_with_draw = false) = 0; //this function can be used from any thread and it takes effect at the begining of the frame, unless sync with draw is used, which is used to mix updates with draw calls + virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, bool p_sync_with_draw = false) = 0; //this function can be used from any thread and it takes effect at the beginning of the frame, unless sync with draw is used, which is used to mix updates with draw calls virtual Vector<uint8_t> buffer_get_data(RID p_buffer) = 0; //this causes stall, only use to retrieve large buffers for saving /*************************/ @@ -643,7 +643,7 @@ public: RENDER_PRIMITIVE_MAX }; - //disable optimization, tesselate control points + //disable optimization, tessellate control points enum PolygonCullMode { POLYGON_CULL_DISABLED, @@ -907,7 +907,7 @@ public: enum InitialAction { INITIAL_ACTION_CLEAR, //start rendering and clear the framebuffer (supply params) INITIAL_ACTION_KEEP, //start rendering, but keep attached color texture contents (depth will be cleared) - INITIAL_ACTION_CONTINUE, //continue rendering (framebuffer must have been left in "continue" state as final action prevously) + INITIAL_ACTION_CONTINUE, //continue rendering (framebuffer must have been left in "continue" state as final action previously) INITIAL_ACTION_MAX }; diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index ed3feccb43..98f1b2e460 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -2198,6 +2198,14 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, OperatorNode *p valid = true; break; } + if (b->parent_function) { + for (int i = 0; i < b->parent_function->arguments.size(); i++) { + if (b->parent_function->arguments[i].name == var_name) { + valid = true; + break; + } + } + } b = b->parent_block; } @@ -3030,7 +3038,7 @@ bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringNam arg->tex_argument_check = true; arg->tex_argument_filter = p_filter; arg->tex_argument_repeat = p_repeat; - for (Map<StringName, Set<int> >::Element *E = arg->tex_argument_connect.front(); E; E = E->next()) { + for (Map<StringName, Set<int>>::Element *E = arg->tex_argument_connect.front(); E; E = E->next()) { for (Set<int>::Element *F = E->get().front(); F; F = F->next()) { if (!_propagate_function_call_sampler_uniform_settings(E->key(), F->get(), p_filter, p_repeat)) { return false; @@ -3065,7 +3073,7 @@ bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringNa arg->tex_builtin_check = true; arg->tex_builtin = p_builtin; - for (Map<StringName, Set<int> >::Element *E = arg->tex_argument_connect.front(); E; E = E->next()) { + for (Map<StringName, Set<int>>::Element *E = arg->tex_argument_connect.front(); E; E = E->next()) { for (Set<int>::Element *F = E->get().front(); F; F = F->next()) { if (!_propagate_function_call_sampler_builtin_reference(E->key(), F->get(), p_builtin)) { return false; @@ -4346,7 +4354,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } } - //consecutively do unary opeators + //consecutively do unary operators for (int i = expr_pos - 1; i >= next_op; i--) { OperatorNode *op = alloc_node<OperatorNode>(); diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h index 5a69a84650..f8391dc273 100644 --- a/servers/visual/shader_language.h +++ b/servers/visual/shader_language.h @@ -576,7 +576,7 @@ public: bool tex_builtin_check; StringName tex_builtin; - Map<StringName, Set<int> > tex_argument_connect; + Map<StringName, Set<int>> tex_argument_connect; }; StringName name; diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 4fea6082f4..09b34ce25c 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -151,8 +151,8 @@ public: //these go pass-through, as they can be called from any thread BIND1R(RID, texture_2d_create, const Ref<Image> &) - BIND2R(RID, texture_2d_layered_create, const Vector<Ref<Image> > &, TextureLayeredType) - BIND1R(RID, texture_3d_create, const Vector<Ref<Image> > &) + BIND2R(RID, texture_2d_layered_create, const Vector<Ref<Image>> &, TextureLayeredType) + BIND1R(RID, texture_3d_create, const Vector<Ref<Image>> &) BIND1R(RID, texture_proxy_create, RID) //goes pass-through diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp index 30fdef9325..43262042cc 100644 --- a/servers/visual/visual_server_viewport.cpp +++ b/servers/visual/visual_server_viewport.cpp @@ -312,7 +312,7 @@ void VisualServerViewport::draw_viewports() { //sort viewports active_viewports.sort_custom<ViewportSort>(); - Map<int, Vector<Rasterizer::BlitToScreen> > blit_to_screen_list; + Map<int, Vector<Rasterizer::BlitToScreen>> blit_to_screen_list; //draw viewports RENDER_TIMESTAMP(">Render Viewports"); @@ -415,7 +415,7 @@ void VisualServerViewport::draw_viewports() { //this needs to be called to make screen swapping more efficient VSG::rasterizer->prepare_for_blitting_render_targets(); - for (Map<int, Vector<Rasterizer::BlitToScreen> >::Element *E = blit_to_screen_list.front(); E; E = E->next()) { + for (Map<int, Vector<Rasterizer::BlitToScreen>>::Element *E = blit_to_screen_list.front(); E; E = E->next()) { VSG::rasterizer->blit_render_targets_to_screen(E->key(), E->get().ptr(), E->get().size()); } } diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 2eaafe220b..8f4df6a0e2 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -79,8 +79,8 @@ public: //these go pass-through, as they can be called from any thread virtual RID texture_2d_create(const Ref<Image> &p_image) { return visual_server->texture_2d_create(p_image); } - virtual RID texture_2d_layered_create(const Vector<Ref<Image> > &p_layers, TextureLayeredType p_layered_type) { return visual_server->texture_2d_layered_create(p_layers, p_layered_type); } - virtual RID texture_3d_create(const Vector<Ref<Image> > &p_slices) { return visual_server->texture_3d_create(p_slices); } + virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, TextureLayeredType p_layered_type) { return visual_server->texture_2d_layered_create(p_layers, p_layered_type); } + virtual RID texture_3d_create(const Vector<Ref<Image>> &p_slices) { return visual_server->texture_3d_create(p_slices); } virtual RID texture_proxy_create(RID p_base) { return visual_server->texture_proxy_create(p_base); } //goes pass-through diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index b30d5e1dd1..1506561952 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -1020,7 +1020,7 @@ Error VisualServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surface_ Error err = _surface_set_data(p_arrays, format, offsets, total_elem_size, vertex_array, array_len, index_array, index_array_len, aabb, bone_aabb); ERR_FAIL_COND_V_MSG(err != OK, ERR_INVALID_DATA, "Invalid array format for surface."); - Vector<Vector<uint8_t> > blend_shape_data; + Vector<Vector<uint8_t>> blend_shape_data; for (int i = 0; i < p_blend_shapes.size(); i++) { @@ -1517,7 +1517,7 @@ Array VisualServer::mesh_surface_get_blend_shape_arrays(RID p_mesh, int p_surfac SurfaceData sd = mesh_get_surface(p_mesh, p_surface); ERR_FAIL_COND_V(sd.vertex_count == 0, Array()); - Vector<Vector<uint8_t> > blend_shape_data = sd.blend_shapes; + Vector<Vector<uint8_t>> blend_shape_data = sd.blend_shapes; if (blend_shape_data.size() > 0) { int vertex_len = sd.vertex_count; diff --git a/servers/visual_server.h b/servers/visual_server.h index 9129f940ee..4bb1c1a080 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -94,8 +94,8 @@ public: }; virtual RID texture_2d_create(const Ref<Image> &p_image) = 0; - virtual RID texture_2d_layered_create(const Vector<Ref<Image> > &p_layers, TextureLayeredType p_layered_type) = 0; - virtual RID texture_3d_create(const Vector<Ref<Image> > &p_slices) = 0; //all slices, then all the mipmaps, must be coherent + virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, TextureLayeredType p_layered_type) = 0; + virtual RID texture_3d_create(const Vector<Ref<Image>> &p_slices) = 0; //all slices, then all the mipmaps, must be coherent virtual RID texture_proxy_create(RID p_base) = 0; virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; //mostly used for video and streaming @@ -262,7 +262,7 @@ public: Vector<LOD> lods; Vector<AABB> bone_aabbs; - Vector<Vector<uint8_t> > blend_shapes; + Vector<Vector<uint8_t>> blend_shapes; RID material; }; diff --git a/thirdparty/README.md b/thirdparty/README.md index 5c9c114ad1..b52b68fe47 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -32,7 +32,7 @@ Files extracted from upstream source: Files extracted from upstream source: -- `.cpp` and `.h` files in root folder +- `.cpp` and `.h` files in root folder except for `basisu_tool.cpp` (contains `main` and can cause link error) - `.cpp`, `.h` and `.inc` files in `transcoder/`, keeping folder structure - `LICENSE` diff --git a/thirdparty/basis_universal/basisu_tool.cpp b/thirdparty/basis_universal/basisu_tool.cpp deleted file mode 100644 index 8172a8c5cc..0000000000 --- a/thirdparty/basis_universal/basisu_tool.cpp +++ /dev/null @@ -1,1548 +0,0 @@ -// basisu_tool.cpp -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#include "transcoder/basisu.h" -#include "transcoder/basisu_transcoder_internal.h" -#include "basisu_enc.h" -#include "basisu_etc.h" -#include "basisu_gpu_texture.h" -#include "basisu_frontend.h" -#include "basisu_backend.h" -#include "transcoder/basisu_global_selector_palette.h" -#include "basisu_comp.h" -#include "transcoder/basisu_transcoder.h" -#include "basisu_ssim.h" - -#define BASISU_CATCH_EXCEPTIONS 1 - -using namespace basisu; - -#define BASISU_TOOL_VERSION "1.10.00" - -enum tool_mode -{ - cDefault, - cCompress, - cValidate, - cUnpack, - cCompare, - cVersion, -}; - -static void print_usage() -{ - printf("\nUsage: basisu filename [filename ...] <options>\n"); - - puts("\n" - "The default mode is compression of one or more PNG files to a .basis file. Alternate modes:\n" - " -unpack: Use transcoder to unpack .basis file to one or more .ktx/.png files\n" - " -validate: Validate and display information about a .basis file\n" - " -compare: Compare two PNG images specified with -file, output PSNR and SSIM statistics and RGB/A delta images\n" - " -version: Print basisu version and exit\n" - "Unless an explicit mode is specified, if one or more files have the .basis extension this tool defaults to unpack mode.\n" - "\n" - "Important: By default, the compressor assumes the input is in the sRGB colorspace (like photos/albedo textures).\n" - "If the input is NOT sRGB (like a normal map), be sure to specify -linear for less artifacts. Depending on the content type, some experimentation may be needed.\n" - "\n" - "Filenames prefixed with a @ symbol are read as filename listing files. Listing text files specify which actual filenames to process (one filename per line).\n" - "\n" - "Options:\n" - " -file filename.png: Input image filename, multiple images are OK, use -file X for each input filename (prefixing input filenames with -file is optional)\n" - " -alpha_file filename.png: Input alpha image filename, multiple images are OK, use -file X for each input filename (must be paired with -file), images converted to REC709 grayscale and used as input alpha\n" - " -multifile_printf: printf() format strint to use to compose multiple filenames\n" - " -multifile_first: The index of the first file to process, default is 0 (must specify -multifile_printf and -multifile_num)\n" - " -multifile_num: The total number of files to process.\n" - " -q X: Set quality level, 1-255, default is 128, lower=better compression/lower quality/faster, higher=less compression/higher quality/slower, default is 128. For even higher quality, use -max_endpoints/-max_selectors.\n" - " -linear: Use linear colorspace metrics (instead of the default sRGB), and by default linear (not sRGB) mipmap filtering.\n" - " -output_file filename: Output .basis/.ktx filename\n" - " -output_path: Output .basis/.ktx files to specified directory.\n" - " -debug: Enable codec debug print to stdout (slightly slower).\n" - " -debug_images: Enable codec debug images (much slower).\n" - " -stats: Compute and display image quality metrics (slightly slower).\n" - " -tex_type <2d, 2darray, 3d, video, cubemap>: Set Basis file header's texture type field. Cubemap arrays require multiples of 6 images, in X+, X-, Y+, Y-, Z+, Z- order, each image must be the same resolutions.\n" - " 2d=arbitrary 2D images, 2darray=2D array, 3D=volume texture slices, video=video frames, cubemap=array of faces. For 2darray/3d/cubemaps/video, each source image's dimensions and # of mipmap levels must be the same.\n" - " For video, the .basis file will be written with the first frame being an I-Frame, and subsequent frames being P-Frames (using conditional replenishment). Playback must always occur in order from first to last image.\n" - " -framerate X: Set framerate in header to X/frames sec.\n" - " -individual: Process input images individually and output multiple .basis files (not as a texture array)\n" - " -comp_level X: Set encoding speed vs. quality tradeoff. Range is 0-5, default is 1. Higher values=MUCH slower, but slightly higher quality. Mostly intended for videos. Use -q first!\n" - " -fuzz_testing: Use with -validate: Disables CRC16 validation of file contents before transcoding\n" - "\n" - "More options:\n" - " -max_endpoints X: Manually set the max number of color endpoint clusters from 1-16128, use instead of -q\n" - " -max_selectors X: Manually set the max number of color selector clusters from 1-16128, use instead of -q\n" - " -y_flip: Flip input images vertically before compression\n" - " -normal_map: Tunes codec parameters for better quality on normal maps (linear colorspace metrics, linear mipmap filtering, no selector RDO, no sRGB)\n" - " -no_alpha: Always output non-alpha basis files, even if one or more inputs has alpha\n" - " -force_alpha: Always output alpha basis files, even if no inputs has alpha\n" - " -separate_rg_to_color_alpha: Separate input R and G channels to RGB and A (for tangent space XY normal maps)\n" - " -no_multithreading: Disable multithreading\n" - " -no_ktx: Disable KTX writing when unpacking (faster)\n" - " -etc1_only: Only unpack to ETC1, skipping the other texture formats during -unpack\n" - " -disable_hierarchical_endpoint_codebooks: Disable hierarchical endpoint codebook usage, slower but higher quality on some compression levels\n" - " -compare_ssim: Compute and display SSIM of image comparison (slow)\n" - "\n" - "Mipmap generation options:\n" - " -mipmap: Generate mipmaps for each source image\n" - " -mip_srgb: Convert image to linear before filtering, then back to sRGB\n" - " -mip_linear: Keep image in linear light during mipmap filtering\n" - " -mip_scale X: Set mipmap filter kernel's scale, lower=sharper, higher=more blurry, default is 1.0\n" - " -mip_filter X: Set mipmap filter kernel, default is kaiser, filters: box, tent, bell, blackman, catmullrom, mitchell, etc.\n" - " -mip_renorm: Renormalize normal map to unit length vectors after filtering\n" - " -mip_clamp: Use clamp addressing on borders, instead of wrapping\n" - " -mip_smallest X: Set smallest pixel dimension for generated mipmaps, default is 1 pixel\n" - "By default, mipmap filtering will occur in sRGB space (for the RGB color channels) unless -linear is specified. You can override this behavior with -mip_srgb/-mip_linear.\n" - "\n" - "Backend endpoint/selector RDO codec options:\n" - " -no_selector_rdo: Disable backend's selector rate distortion optimizations (slightly faster, less noisy output, but lower quality per output bit)\n" - " -selector_rdo_thresh X: Set selector RDO quality threshold, default is 1.25, lower is higher quality but less quality per output bit (try 1.0-3.0)\n" - " -no_endpoint_rdo: Disable backend's endpoint rate distortion optimizations (slightly faster, less noisy output, but lower quality per output bit)\n" - " -endpoint_rdo_thresh X: Set endpoint RDO quality threshold, default is 1.5, lower is higher quality but less quality per output bit (try 1.0-3.0)\n" - "\n" - "Hierarchical virtual selector codebook options:\n" - " -global_sel_pal: Always use vitual selector palettes (instead of custom palettes), slightly smaller files, but lower quality, slower encoding\n" - " -auto_global_sel_pal: Automatically use virtual selector palettes on small images for slightly smaller files (defaults to off for faster encoding time)\n" - " -no_hybrid_sel_cb: Don't automatically use hybrid virtual selector codebooks (for higher quality, only active when -global_sel_pal is specified)\n" - " -global_pal_bits X: Set virtual selector codebook palette bits, range is [0,12], default is 8, higher is slower/better quality\n" - " -global_mod_bits X: Set virtual selector codebook modifier bits, range is [0,15], defualt is 8, higher is slower/better quality\n" - " -hybrid_sel_cb_quality_thresh X: Set hybrid selector codebook quality threshold, default is 2.0, try 1.5-3, higher is lower quality/smaller codebooks\n" - "\n" - "Set various fields in the Basis file header:\n" - " -userdata0 X: Set 32-bit userdata0 field in Basis file header to X (X is a signed 32-bit int)\n" - " -userdata1 X: Set 32-bit userdata1 field in Basis file header to X (X is a signed 32-bit int)\n" - "\n" - "Various command line examples:\n" - " basisu x.png : Compress sRGB image x.png to x.basis using default settings (multiple filenames OK)\n" - " basisu x.basis : Unpack x.basis to PNG/KTX files (multiple filenames OK)\n" - " basisu -file x.png -mipmap -y_flip : Compress a mipmapped x.basis file from an sRGB image named x.png, Y flip each source image\n" - " basisu -validate -file x.basis : Validate x.basis (check header, check file CRC's, attempt to transcode all slices)\n" - " basisu -unpack -file x.basis : Validates, transcodes and unpacks x.basis to mipmapped .KTX and RGB/A .PNG files (transcodes to all supported GPU texture formats)\n" - " basisu -q 255 -file x.png -mipmap -debug -stats : Compress sRGB x.png to x.basis at quality level 255 with compressor debug output/statistics\n" - " basisu -linear -max_endpoints 16128 -max_selectors 16128 -file x.png : Compress non-sRGB x.png to x.basis using the largest supported manually specified codebook sizes\n" - " basisu -linear -global_sel_pal -no_hybrid_sel_cb -file x.png : Compress a non-sRGB image, use virtual selector codebooks for improved compression (but slower encoding)\n" - " basisu -linear -global_sel_pal -file x.png: Compress a non-sRGB image, use hybrid selector codebooks for slightly improved compression (but slower encoding)\n" - " basisu -tex_type video -framerate 20 -multifile_printf \"x%02u.png\" -multifile_first 1 -multifile_count 20 : Compress a 20 sRGB source image video sequence (x01.png, x02.png, x03.png, etc.) to x01.basis\n" - "\n" - "Note: For video use, it's recommended you use a very powerful machine with many cores. Use -slower for better codebook generation, specify very large codebooks using -max_endpoints and -max_selectors, and reduce\n" - "the default endpoint RDO threshold (-endpoint_rdo_thresh) to around 1.25. Videos may have mipmaps and alpha channels. Videos must always be played back by the transcoder in first to last image order.\n" - "Video files currently use I-Frames on the first image, and P-Frames using conditional replenishment on subsequent frames.\n" - "Compression level details:\n" - " Level 0: Fastest, but has marginal quality and is a work in progress. Brittle on complex images. Avg. Y dB: 35.45\n" - " Level 1: Hierarchical codebook searching. 36.87 dB, ~1.4x slower vs. level 0. (This is the default setting.)\n" - " Level 2: Full codebook searching. 37.13 dB, ~1.8x slower vs. level 0. (Equivalent the the initial release's default settings.)\n" - " Level 3: Hierarchical codebook searching, codebook k-means iterations. 37.15 dB, ~4x slower vs. level 0\n" - " Level 4: Full codebook searching, codebook k-means iterations. 37.41 dB, ~5.5x slower vs. level 0. (Equivalent to the initial release's -slower setting.)\n" - " Level 5: Full codebook searching, twice as many codebook k-means iterations, best ETC1 endpoint opt. 37.43 dB, ~12x slower vs. level 0\n" - ); -} - -static bool load_listing_file(const std::string &f, std::vector<std::string> &filenames) -{ - std::string filename(f); - filename.erase(0, 1); - - FILE *pFile = nullptr; -#ifdef _WIN32 - fopen_s(&pFile, filename.c_str(), "r"); -#else - pFile = fopen(filename.c_str(), "r"); -#endif - - if (!pFile) - { - error_printf("Failed opening listing file: \"%s\"\n", filename.c_str()); - return false; - } - - uint32_t total_filenames = 0; - - for ( ; ; ) - { - char buf[3072]; - buf[0] = '\0'; - - char *p = fgets(buf, sizeof(buf), pFile); - if (!p) - { - if (ferror(pFile)) - { - error_printf("Failed reading from listing file: \"%s\"\n", filename.c_str()); - - fclose(pFile); - return false; - } - else - break; - } - - std::string read_filename(p); - while (read_filename.size()) - { - if (read_filename[0] == ' ') - read_filename.erase(0, 1); - else - break; - } - - while (read_filename.size()) - { - const char c = read_filename.back(); - if ((c == ' ') || (c == '\n') || (c == '\r')) - read_filename.erase(read_filename.size() - 1, 1); - else - break; - } - - if (read_filename.size()) - { - filenames.push_back(read_filename); - total_filenames++; - } - } - - fclose(pFile); - - printf("Successfully read %u filenames(s) from listing file \"%s\"\n", total_filenames, filename.c_str()); - - return true; -} - -class command_line_params -{ - BASISU_NO_EQUALS_OR_COPY_CONSTRUCT(command_line_params); - -public: - command_line_params() : - m_mode(cDefault), - m_multifile_first(0), - m_multifile_num(0), - m_individual(false), - m_no_ktx(false), - m_etc1_only(false), - m_fuzz_testing(false), - m_compare_ssim(false) - { - } - - bool parse(int arg_c, const char **arg_v) - { - int arg_index = 1; - while (arg_index < arg_c) - { - const char *pArg = arg_v[arg_index]; - const int num_remaining_args = arg_c - (arg_index + 1); - int arg_count = 1; - -#define REMAINING_ARGS_CHECK(n) if (num_remaining_args < (n)) { error_printf("Error: Expected %u values to follow %s!\n", n, pArg); return false; } - - if (strcasecmp(pArg, "-compress") == 0) - m_mode = cCompress; - else if (strcasecmp(pArg, "-compare") == 0) - m_mode = cCompare; - else if (strcasecmp(pArg, "-unpack") == 0) - m_mode = cUnpack; - else if (strcasecmp(pArg, "-validate") == 0) - m_mode = cValidate; - else if (strcasecmp(pArg, "-version") == 0) - m_mode = cVersion; - else if (strcasecmp(pArg, "-compare_ssim") == 0) - m_compare_ssim = true; - else if (strcasecmp(pArg, "-file") == 0) - { - REMAINING_ARGS_CHECK(1); - m_input_filenames.push_back(std::string(arg_v[arg_index + 1])); - arg_count++; - } - else if (strcasecmp(pArg, "-alpha_file") == 0) - { - REMAINING_ARGS_CHECK(1); - m_input_alpha_filenames.push_back(std::string(arg_v[arg_index + 1])); - arg_count++; - } - else if (strcasecmp(pArg, "-multifile_printf") == 0) - { - REMAINING_ARGS_CHECK(1); - m_multifile_printf = std::string(arg_v[arg_index + 1]); - arg_count++; - } - else if (strcasecmp(pArg, "-multifile_first") == 0) - { - REMAINING_ARGS_CHECK(1); - m_multifile_first = atoi(arg_v[arg_index + 1]); - arg_count++; - } - else if (strcasecmp(pArg, "-multifile_num") == 0) - { - REMAINING_ARGS_CHECK(1); - m_multifile_num = atoi(arg_v[arg_index + 1]); - arg_count++; - } - else if (strcasecmp(pArg, "-linear") == 0) - m_comp_params.m_perceptual = false; - else if (strcasecmp(pArg, "-srgb") == 0) - m_comp_params.m_perceptual = true; - else if (strcasecmp(pArg, "-q") == 0) - { - REMAINING_ARGS_CHECK(1); - m_comp_params.m_quality_level = clamp<int>(atoi(arg_v[arg_index + 1]), BASISU_QUALITY_MIN, BASISU_QUALITY_MAX); - arg_count++; - } - else if (strcasecmp(pArg, "-output_file") == 0) - { - REMAINING_ARGS_CHECK(1); - m_output_filename = arg_v[arg_index + 1]; - arg_count++; - } - else if (strcasecmp(pArg, "-output_path") == 0) - { - REMAINING_ARGS_CHECK(1); - m_output_path = arg_v[arg_index + 1]; - arg_count++; - } - else if (strcasecmp(pArg, "-debug") == 0) - { - m_comp_params.m_debug = true; - enable_debug_printf(true); - } - else if (strcasecmp(pArg, "-debug_images") == 0) - m_comp_params.m_debug_images = true; - else if (strcasecmp(pArg, "-stats") == 0) - m_comp_params.m_compute_stats = true; - else if (strcasecmp(pArg, "-comp_level") == 0) - { - REMAINING_ARGS_CHECK(1); - m_comp_params.m_compression_level = atoi(arg_v[arg_index + 1]); - arg_count++; - } - else if (strcasecmp(pArg, "-slower") == 0) - { - // This option is gone, but we'll do something reasonable with it anyway. Level 4 is equivalent to the original release's -slower, but let's just go to level 2. - m_comp_params.m_compression_level = 2; - } - else if (strcasecmp(pArg, "-max_endpoints") == 0) - { - REMAINING_ARGS_CHECK(1); - m_comp_params.m_max_endpoint_clusters = clamp<int>(atoi(arg_v[arg_index + 1]), 1, BASISU_MAX_ENDPOINT_CLUSTERS); - arg_count++; - } - else if (strcasecmp(pArg, "-max_selectors") == 0) - { - REMAINING_ARGS_CHECK(1); - m_comp_params.m_max_selector_clusters = clamp<int>(atoi(arg_v[arg_index + 1]), 1, BASISU_MAX_SELECTOR_CLUSTERS); - arg_count++; - } - else if (strcasecmp(pArg, "-y_flip") == 0) - m_comp_params.m_y_flip = true; - else if (strcasecmp(pArg, "-normal_map") == 0) - { - m_comp_params.m_perceptual = false; - m_comp_params.m_mip_srgb = false; - m_comp_params.m_no_selector_rdo = true; - m_comp_params.m_no_endpoint_rdo = true; - } - else if (strcasecmp(pArg, "-no_alpha") == 0) - m_comp_params.m_check_for_alpha = false; - else if (strcasecmp(pArg, "-force_alpha") == 0) - m_comp_params.m_force_alpha = true; - else if ((strcasecmp(pArg, "-separate_rg_to_color_alpha") == 0) || - (strcasecmp(pArg, "-seperate_rg_to_color_alpha") == 0)) // was mispelled for a while - whoops! - m_comp_params.m_seperate_rg_to_color_alpha = true; - else if (strcasecmp(pArg, "-no_multithreading") == 0) - { - m_comp_params.m_multithreading = false; - } - else if (strcasecmp(pArg, "-mipmap") == 0) - m_comp_params.m_mip_gen = true; - else if (strcasecmp(pArg, "-no_ktx") == 0) - m_no_ktx = true; - else if (strcasecmp(pArg, "-etc1_only") == 0) - m_etc1_only = true; - else if (strcasecmp(pArg, "-disable_hierarchical_endpoint_codebooks") == 0) - m_comp_params.m_disable_hierarchical_endpoint_codebooks = true; - else if (strcasecmp(pArg, "-mip_scale") == 0) - { - REMAINING_ARGS_CHECK(1); - m_comp_params.m_mip_scale = (float)atof(arg_v[arg_index + 1]); - arg_count++; - } - else if (strcasecmp(pArg, "-mip_filter") == 0) - { - REMAINING_ARGS_CHECK(1); - m_comp_params.m_mip_filter = arg_v[arg_index + 1]; - // TODO: Check filter - arg_count++; - } - else if (strcasecmp(pArg, "-mip_renorm") == 0) - m_comp_params.m_mip_renormalize = true; - else if (strcasecmp(pArg, "-mip_clamp") == 0) - m_comp_params.m_mip_wrapping = false; - else if (strcasecmp(pArg, "-mip_smallest") == 0) - { - REMAINING_ARGS_CHECK(1); - m_comp_params.m_mip_smallest_dimension = atoi(arg_v[arg_index + 1]); - arg_count++; - } - else if (strcasecmp(pArg, "-mip_srgb") == 0) - m_comp_params.m_mip_srgb = true; - else if (strcasecmp(pArg, "-mip_linear") == 0) - m_comp_params.m_mip_srgb = false; - else if (strcasecmp(pArg, "-no_selector_rdo") == 0) - m_comp_params.m_no_selector_rdo = true; - else if (strcasecmp(pArg, "-selector_rdo_thresh") == 0) - { - REMAINING_ARGS_CHECK(1); - m_comp_params.m_selector_rdo_thresh = (float)atof(arg_v[arg_index + 1]); - arg_count++; - } - else if (strcasecmp(pArg, "-no_endpoint_rdo") == 0) - m_comp_params.m_no_endpoint_rdo = true; - else if (strcasecmp(pArg, "-endpoint_rdo_thresh") == 0) - { - REMAINING_ARGS_CHECK(1); - m_comp_params.m_endpoint_rdo_thresh = (float)atof(arg_v[arg_index + 1]); - arg_count++; - } - else if (strcasecmp(pArg, "-global_sel_pal") == 0) - m_comp_params.m_global_sel_pal = true; - else if (strcasecmp(pArg, "-no_auto_global_sel_pal") == 0) - m_comp_params.m_auto_global_sel_pal = false; - else if (strcasecmp(pArg, "-auto_global_sel_pal") == 0) - m_comp_params.m_auto_global_sel_pal = true; - else if (strcasecmp(pArg, "-global_pal_bits") == 0) - { - REMAINING_ARGS_CHECK(1); - m_comp_params.m_global_pal_bits = atoi(arg_v[arg_index + 1]); - arg_count++; - } - else if (strcasecmp(pArg, "-global_mod_bits") == 0) - { - REMAINING_ARGS_CHECK(1); - m_comp_params.m_global_mod_bits = atoi(arg_v[arg_index + 1]); - arg_count++; - } - else if (strcasecmp(pArg, "-no_hybrid_sel_cb") == 0) - m_comp_params.m_no_hybrid_sel_cb = true; - else if (strcasecmp(pArg, "-hybrid_sel_cb_quality_thresh") == 0) - { - REMAINING_ARGS_CHECK(1); - m_comp_params.m_hybrid_sel_cb_quality_thresh = (float)atof(arg_v[arg_index + 1]); - arg_count++; - } - else if (strcasecmp(pArg, "-userdata0") == 0) - { - REMAINING_ARGS_CHECK(1); - m_comp_params.m_userdata0 = atoi(arg_v[arg_index + 1]); - arg_count++; - } - else if (strcasecmp(pArg, "-userdata1") == 0) - { - REMAINING_ARGS_CHECK(1); - m_comp_params.m_userdata1 = atoi(arg_v[arg_index + 1]); - arg_count++; - } - else if (strcasecmp(pArg, "-framerate") == 0) - { - REMAINING_ARGS_CHECK(1); - double fps = atof(arg_v[arg_index + 1]); - double us_per_frame = 0; - if (fps > 0) - us_per_frame = 1000000.0f / fps; - - m_comp_params.m_us_per_frame = clamp<int>(static_cast<int>(us_per_frame + .5f), 0, basist::cBASISMaxUSPerFrame); - arg_count++; - } - else if (strcasecmp(pArg, "-tex_type") == 0) - { - REMAINING_ARGS_CHECK(1); - const char *pType = arg_v[arg_index + 1]; - if (strcasecmp(pType, "2d") == 0) - m_comp_params.m_tex_type = basist::cBASISTexType2D; - else if (strcasecmp(pType, "2darray") == 0) - m_comp_params.m_tex_type = basist::cBASISTexType2DArray; - else if (strcasecmp(pType, "3d") == 0) - m_comp_params.m_tex_type = basist::cBASISTexTypeVolume; - else if (strcasecmp(pType, "cubemap") == 0) - m_comp_params.m_tex_type = basist::cBASISTexTypeCubemapArray; - else if (strcasecmp(pType, "video") == 0) - m_comp_params.m_tex_type = basist::cBASISTexTypeVideoFrames; - else - { - error_printf("Invalid texture type: %s\n", pType); - return false; - } - arg_count++; - } - else if (strcasecmp(pArg, "-individual") == 0) - m_individual = true; - else if (strcasecmp(pArg, "-fuzz_testing") == 0) - m_fuzz_testing = true; - else if (strcasecmp(pArg, "-csv_file") == 0) - { - REMAINING_ARGS_CHECK(1); - m_csv_file = arg_v[arg_index + 1]; - m_comp_params.m_compute_stats = true; - - arg_count++; - } - else if (pArg[0] == '-') - { - error_printf("Unrecognized command line option: %s\n", pArg); - return false; - } - else - { - // Let's assume it's a source filename, so globbing works - //error_printf("Unrecognized command line option: %s\n", pArg); - m_input_filenames.push_back(pArg); - } - - arg_index += arg_count; - } - - if (m_comp_params.m_quality_level != -1) - { - m_comp_params.m_max_endpoint_clusters = 0; - m_comp_params.m_max_selector_clusters = 0; - } - else if ((!m_comp_params.m_max_endpoint_clusters) || (!m_comp_params.m_max_selector_clusters)) - { - m_comp_params.m_max_endpoint_clusters = 0; - m_comp_params.m_max_selector_clusters = 0; - - m_comp_params.m_quality_level = 128; - } - - if (!m_comp_params.m_mip_srgb.was_changed()) - { - // They didn't specify what colorspace to do mipmap filtering in, so choose sRGB if they've specified that the texture is sRGB. - if (m_comp_params.m_perceptual) - m_comp_params.m_mip_srgb = true; - else - m_comp_params.m_mip_srgb = false; - } - - return true; - } - - bool process_listing_files() - { - std::vector<std::string> new_input_filenames; - for (uint32_t i = 0; i < m_input_filenames.size(); i++) - { - if (m_input_filenames[i][0] == '@') - { - if (!load_listing_file(m_input_filenames[i], new_input_filenames)) - return false; - } - else - new_input_filenames.push_back(m_input_filenames[i]); - } - new_input_filenames.swap(m_input_filenames); - - std::vector<std::string> new_input_alpha_filenames; - for (uint32_t i = 0; i < m_input_alpha_filenames.size(); i++) - { - if (m_input_alpha_filenames[i][0] == '@') - { - if (!load_listing_file(m_input_alpha_filenames[i], new_input_alpha_filenames)) - return false; - } - else - new_input_alpha_filenames.push_back(m_input_alpha_filenames[i]); - } - new_input_alpha_filenames.swap(m_input_alpha_filenames); - - return true; - } - - basis_compressor_params m_comp_params; - - tool_mode m_mode; - - std::vector<std::string> m_input_filenames; - std::vector<std::string> m_input_alpha_filenames; - - std::string m_output_filename; - std::string m_output_path; - - std::string m_multifile_printf; - uint32_t m_multifile_first; - uint32_t m_multifile_num; - - std::string m_csv_file; - - bool m_individual; - bool m_no_ktx; - bool m_etc1_only; - bool m_fuzz_testing; - bool m_compare_ssim; -}; - -static bool expand_multifile(command_line_params &opts) -{ - if (!opts.m_multifile_printf.size()) - return true; - - if (!opts.m_multifile_num) - { - error_printf("-multifile_printf specified, but not -multifile_num\n"); - return false; - } - - std::string fmt(opts.m_multifile_printf); - size_t x = fmt.find_first_of('!'); - if (x != std::string::npos) - fmt[x] = '%'; - - if (string_find_right(fmt, '%') == -1) - { - error_printf("Must include C-style printf() format character '%%' in -multifile_printf string\n"); - return false; - } - - for (uint32_t i = opts.m_multifile_first; i < opts.m_multifile_first + opts.m_multifile_num; i++) - { - char buf[1024]; -#ifdef _WIN32 - sprintf_s(buf, sizeof(buf), fmt.c_str(), i); -#else - snprintf(buf, sizeof(buf), fmt.c_str(), i); -#endif - - if (buf[0]) - opts.m_input_filenames.push_back(buf); - } - - return true; -} - -static bool compress_mode(command_line_params &opts) -{ - basist::etc1_global_selector_codebook sel_codebook(basist::g_global_selector_cb_size, basist::g_global_selector_cb); - - uint32_t num_threads = 1; - - if (opts.m_comp_params.m_multithreading) - { - num_threads = std::thread::hardware_concurrency(); - if (num_threads < 1) - num_threads = 1; - } - - job_pool jpool(num_threads); - opts.m_comp_params.m_pJob_pool = &jpool; - - if (!expand_multifile(opts)) - { - error_printf("-multifile expansion failed!\n"); - return false; - } - - if (!opts.m_input_filenames.size()) - { - error_printf("No input files to process!\n"); - return false; - } - - basis_compressor_params ¶ms = opts.m_comp_params; - - params.m_read_source_images = true; - params.m_write_output_basis_files = true; - params.m_pSel_codebook = &sel_codebook; - - FILE *pCSV_file = nullptr; - if (opts.m_csv_file.size()) - { - pCSV_file = fopen_safe(opts.m_csv_file.c_str(), "a"); - if (!pCSV_file) - { - error_printf("Failed opening CVS file \"%s\"\n", opts.m_csv_file.c_str()); - return false; - } - } - - printf("Processing %u total files\n", (uint32_t)opts.m_input_filenames.size()); - - for (size_t file_index = 0; file_index < (opts.m_individual ? opts.m_input_filenames.size() : 1U); file_index++) - { - if (opts.m_individual) - { - params.m_source_filenames.resize(1); - params.m_source_filenames[0] = opts.m_input_filenames[file_index]; - - if (file_index < opts.m_input_alpha_filenames.size()) - { - params.m_source_alpha_filenames.resize(1); - params.m_source_alpha_filenames[0] = opts.m_input_alpha_filenames[file_index]; - - printf("Processing source file \"%s\", alpha file \"%s\"\n", params.m_source_filenames[0].c_str(), params.m_source_alpha_filenames[0].c_str()); - } - else - { - params.m_source_alpha_filenames.resize(0); - - printf("Processing source file \"%s\"\n", params.m_source_filenames[0].c_str()); - } - } - else - { - params.m_source_filenames = opts.m_input_filenames; - params.m_source_alpha_filenames = opts.m_input_alpha_filenames; - } - - if ((opts.m_output_filename.size()) && (!opts.m_individual)) - params.m_out_filename = opts.m_output_filename; - else - { - std::string filename; - - string_get_filename(opts.m_input_filenames[file_index].c_str(), filename); - string_remove_extension(filename); - filename += ".basis"; - - if (opts.m_output_path.size()) - string_combine_path(filename, opts.m_output_path.c_str(), filename.c_str()); - - params.m_out_filename = filename; - } - - basis_compressor c; - - if (!c.init(opts.m_comp_params)) - { - error_printf("basis_compressor::init() failed!\n"); - - if (pCSV_file) - { - fclose(pCSV_file); - pCSV_file = nullptr; - } - - return false; - } - - interval_timer tm; - tm.start(); - - basis_compressor::error_code ec = c.process(); - - tm.stop(); - - if (ec == basis_compressor::cECSuccess) - { - printf("Compression succeeded to file \"%s\" in %3.3f secs\n", params.m_out_filename.c_str(), tm.get_elapsed_secs()); - } - else - { - bool exit_flag = true; - - switch (ec) - { - case basis_compressor::cECFailedReadingSourceImages: - { - error_printf("Compressor failed reading a source image!\n"); - - if (opts.m_individual) - exit_flag = false; - - break; - } - case basis_compressor::cECFailedValidating: - error_printf("Compressor failed 2darray/cubemap/video validation checks!\n"); - break; - case basis_compressor::cECFailedFrontEnd: - error_printf("Compressor frontend stage failed!\n"); - break; - case basis_compressor::cECFailedFontendExtract: - error_printf("Compressor frontend data extraction failed!\n"); - break; - case basis_compressor::cECFailedBackend: - error_printf("Compressor backend stage failed!\n"); - break; - case basis_compressor::cECFailedCreateBasisFile: - error_printf("Compressor failed creating Basis file data!\n"); - break; - case basis_compressor::cECFailedWritingOutput: - error_printf("Compressor failed writing to output Basis file!\n"); - break; - default: - error_printf("basis_compress::process() failed!\n"); - break; - } - - if (exit_flag) - { - if (pCSV_file) - { - fclose(pCSV_file); - pCSV_file = nullptr; - } - - return false; - } - } - - if ((pCSV_file) && (c.get_stats().size())) - { - for (size_t slice_index = 0; slice_index < c.get_stats().size(); slice_index++) - { - fprintf(pCSV_file, "\"%s\", %u, %u, %u, %u, %u, %f, %f, %f, %f, %u, %u, %f\n", - params.m_out_filename.c_str(), - (uint32_t)slice_index, (uint32_t)c.get_stats().size(), - c.get_stats()[slice_index].m_width, c.get_stats()[slice_index].m_height, (uint32_t)c.get_any_source_image_has_alpha(), - c.get_basis_bits_per_texel(), - c.get_stats()[slice_index].m_best_luma_709_psnr, - c.get_stats()[slice_index].m_basis_etc1s_luma_709_psnr, - c.get_stats()[slice_index].m_basis_bc1_luma_709_psnr, - params.m_quality_level, (int)params.m_compression_level, tm.get_elapsed_secs()); - fflush(pCSV_file); - } - } - - if (opts.m_individual) - printf("\n"); - - } // file_index - - if (pCSV_file) - { - fclose(pCSV_file); - pCSV_file = nullptr; - } - - return true; -} - -static bool unpack_and_validate_mode(command_line_params &opts, bool validate_flag) -{ - basist::etc1_global_selector_codebook sel_codebook(basist::g_global_selector_cb_size, basist::g_global_selector_cb); - - if (!opts.m_input_filenames.size()) - { - error_printf("No input files to process!\n"); - return false; - } - - uint32_t total_unpack_warnings = 0; - uint32_t total_pvrtc_nonpow2_warnings = 0; - - for (uint32_t file_index = 0; file_index < opts.m_input_filenames.size(); file_index++) - { - const char* pInput_filename = opts.m_input_filenames[file_index].c_str(); - - std::string base_filename; - string_split_path(pInput_filename, nullptr, nullptr, &base_filename, nullptr); - - uint8_vec basis_data; - if (!basisu::read_file_to_vec(pInput_filename, basis_data)) - { - error_printf("Failed reading file \"%s\"\n", pInput_filename); - return false; - } - - printf("Input file \"%s\"\n", pInput_filename); - - if (!basis_data.size()) - { - error_printf("File is empty!\n"); - return false; - } - - if (basis_data.size() > UINT32_MAX) - { - error_printf("File is too large!\n"); - return false; - } - - basist::basisu_transcoder dec(&sel_codebook); - - if (!opts.m_fuzz_testing) - { - // Skip the full validation, which CRC16's the entire file. - - // Validate the file - note this isn't necessary for transcoding - if (!dec.validate_file_checksums(&basis_data[0], (uint32_t)basis_data.size(), true)) - { - error_printf("File version is unsupported, or file fail CRC checks!\n"); - return false; - } - } - - printf("File version and CRC checks succeeded\n"); - - basist::basisu_file_info fileinfo; - if (!dec.get_file_info(&basis_data[0], (uint32_t)basis_data.size(), fileinfo)) - { - error_printf("Failed retrieving Basis file information!\n"); - return false; - } - - assert(fileinfo.m_total_images == fileinfo.m_image_mipmap_levels.size()); - assert(fileinfo.m_total_images == dec.get_total_images(&basis_data[0], (uint32_t)basis_data.size())); - - printf("File info:\n"); - printf(" Version: %X\n", fileinfo.m_version); - printf(" Total header size: %u\n", fileinfo.m_total_header_size); - printf(" Total selectors: %u\n", fileinfo.m_total_selectors); - printf(" Selector codebook size: %u\n", fileinfo.m_selector_codebook_size); - printf(" Total endpoints: %u\n", fileinfo.m_total_endpoints); - printf(" Endpoint codebook size: %u\n", fileinfo.m_endpoint_codebook_size); - printf(" Tables size: %u\n", fileinfo.m_tables_size); - printf(" Slices size: %u\n", fileinfo.m_slices_size); - printf(" Texture type: %s\n", basist::basis_get_texture_type_name(fileinfo.m_tex_type)); - printf(" us per frame: %u (%f fps)\n", fileinfo.m_us_per_frame, fileinfo.m_us_per_frame ? (1.0f / ((float)fileinfo.m_us_per_frame / 1000000.0f)) : 0.0f); - printf(" Total slices: %u\n", (uint32_t)fileinfo.m_slice_info.size()); - printf(" Total images: %i\n", fileinfo.m_total_images); - printf(" Y Flipped: %u, Has alpha slices: %u\n", fileinfo.m_y_flipped, fileinfo.m_has_alpha_slices); - printf(" userdata0: 0x%X userdata1: 0x%X\n", fileinfo.m_userdata0, fileinfo.m_userdata1); - printf(" Per-image mipmap levels: "); - for (uint32_t i = 0; i < fileinfo.m_total_images; i++) - printf("%u ", fileinfo.m_image_mipmap_levels[i]); - printf("\n"); - - printf("\nImage info:\n"); - for (uint32_t i = 0; i < fileinfo.m_total_images; i++) - { - basist::basisu_image_info ii; - if (!dec.get_image_info(&basis_data[0], (uint32_t)basis_data.size(), ii, i)) - { - error_printf("get_image_info() failed!\n"); - return false; - } - - printf("Image %u: MipLevels: %u OrigDim: %ux%u, BlockDim: %ux%u, FirstSlice: %u, HasAlpha: %u\n", i, ii.m_total_levels, ii.m_orig_width, ii.m_orig_height, - ii.m_num_blocks_x, ii.m_num_blocks_y, ii.m_first_slice_index, (uint32_t)ii.m_alpha_flag); - } - - printf("\nSlice info:\n"); - for (uint32_t i = 0; i < fileinfo.m_slice_info.size(); i++) - { - const basist::basisu_slice_info& sliceinfo = fileinfo.m_slice_info[i]; - printf("%u: OrigWidthHeight: %ux%u, BlockDim: %ux%u, TotalBlocks: %u, Compressed size: %u, Image: %u, Level: %u, UnpackedCRC16: 0x%X, alpha: %u, iframe: %i\n", - i, - sliceinfo.m_orig_width, sliceinfo.m_orig_height, - sliceinfo.m_num_blocks_x, sliceinfo.m_num_blocks_y, - sliceinfo.m_total_blocks, - sliceinfo.m_compressed_size, - sliceinfo.m_image_index, sliceinfo.m_level_index, - sliceinfo.m_unpacked_slice_crc16, - (uint32_t)sliceinfo.m_alpha_flag, - (uint32_t)sliceinfo.m_iframe_flag); - } - printf("\n"); - - interval_timer tm; - tm.start(); - - if (!dec.start_transcoding(&basis_data[0], (uint32_t)basis_data.size())) - { - error_printf("start_transcoding() failed!\n"); - return false; - } - - printf("start_transcoding time: %3.3f ms\n", tm.get_elapsed_ms()); - - std::vector< gpu_image_vec > gpu_images[(int)basist::transcoder_texture_format::cTFTotalTextureFormats]; - - int first_format = 0; - int last_format = (int)basist::transcoder_texture_format::cTFTotalTextureFormats; - - if (opts.m_etc1_only) - { - first_format = (int)basist::transcoder_texture_format::cTFETC1_RGB; - last_format = first_format + 1; - } - - for (int format_iter = first_format; format_iter < last_format; format_iter++) - { - basist::transcoder_texture_format tex_fmt = static_cast<basist::transcoder_texture_format>(format_iter); - - if (basist::basis_transcoder_format_is_uncompressed(tex_fmt)) - continue; - - gpu_images[(int)tex_fmt].resize(fileinfo.m_total_images); - - for (uint32_t image_index = 0; image_index < fileinfo.m_total_images; image_index++) - gpu_images[(int)tex_fmt][image_index].resize(fileinfo.m_image_mipmap_levels[image_index]); - } - - // Now transcode the file to all supported texture formats and save mipmapped KTX files - for (int format_iter = first_format; format_iter < last_format; format_iter++) - { - const basist::transcoder_texture_format transcoder_tex_fmt = static_cast<basist::transcoder_texture_format>(format_iter); - - if (basist::basis_transcoder_format_is_uncompressed(transcoder_tex_fmt)) - continue; - - for (uint32_t image_index = 0; image_index < fileinfo.m_total_images; image_index++) - { - for (uint32_t level_index = 0; level_index < fileinfo.m_image_mipmap_levels[image_index]; level_index++) - { - basist::basisu_image_level_info level_info; - - if (!dec.get_image_level_info(&basis_data[0], (uint32_t)basis_data.size(), level_info, image_index, level_index)) - { - error_printf("Failed retrieving image level information (%u %u)!\n", image_index, level_index); - return false; - } - - if ((transcoder_tex_fmt == basist::transcoder_texture_format::cTFPVRTC1_4_RGB) || (transcoder_tex_fmt == basist::transcoder_texture_format::cTFPVRTC1_4_RGBA)) - { - if (!is_pow2(level_info.m_width) || !is_pow2(level_info.m_height)) - { - total_pvrtc_nonpow2_warnings++; - - printf("Warning: Will not transcode image %u level %u res %ux%u to PVRTC1 (one or more dimension is not a power of 2)\n", image_index, level_index, level_info.m_width, level_info.m_height); - - // Can't transcode this image level to PVRTC because it's not a pow2 (we're going to support transcoding non-pow2 to the next larger pow2 soon) - continue; - } - } - - basisu::texture_format tex_fmt = basis_get_basisu_texture_format(transcoder_tex_fmt); - - gpu_image& gi = gpu_images[(int)transcoder_tex_fmt][image_index][level_index]; - gi.init(tex_fmt, level_info.m_orig_width, level_info.m_orig_height); - - // Fill the buffer with psuedo-random bytes, to help more visibly detect cases where the transcoder fails to write to part of the output. - fill_buffer_with_random_bytes(gi.get_ptr(), gi.get_size_in_bytes()); - - uint32_t decode_flags = 0; - - tm.start(); - - if (!dec.transcode_image_level(&basis_data[0], (uint32_t)basis_data.size(), image_index, level_index, gi.get_ptr(), gi.get_total_blocks(), transcoder_tex_fmt, decode_flags)) - { - error_printf("Failed transcoding image level (%u %u %u)!\n", image_index, level_index, format_iter); - return false; - } - - double total_transcode_time = tm.get_elapsed_ms(); - - printf("Transcode of image %u level %u res %ux%u format %s succeeded in %3.3f ms\n", image_index, level_index, level_info.m_orig_width, level_info.m_orig_height, basist::basis_get_format_name(transcoder_tex_fmt), total_transcode_time); - - } // format_iter - - } // level_index - - } // image_info - - if (!validate_flag) - { - // Now write KTX files and unpack them to individual PNG's - - for (int format_iter = first_format; format_iter < last_format; format_iter++) - { - const basist::transcoder_texture_format transcoder_tex_fmt = static_cast<basist::transcoder_texture_format>(format_iter); - - if (basist::basis_transcoder_format_is_uncompressed(transcoder_tex_fmt)) - continue; - - if ((!opts.m_no_ktx) && (fileinfo.m_tex_type == basist::cBASISTexTypeCubemapArray)) - { - // No KTX tool that we know of supports cubemap arrays, so write individual cubemap files. - for (uint32_t image_index = 0; image_index < fileinfo.m_total_images; image_index += 6) - { - std::vector<gpu_image_vec> cubemap; - for (uint32_t i = 0; i < 6; i++) - cubemap.push_back(gpu_images[format_iter][image_index + i]); - - std::string ktx_filename(base_filename + string_format("_transcoded_cubemap_%s_%u.ktx", basist::basis_get_format_name(transcoder_tex_fmt), image_index / 6)); - if (!write_compressed_texture_file(ktx_filename.c_str(), cubemap, true)) - { - error_printf("Failed writing KTX file \"%s\"!\n", ktx_filename.c_str()); - return false; - } - printf("Wrote KTX file \"%s\"\n", ktx_filename.c_str()); - } - } - - for (uint32_t image_index = 0; image_index < fileinfo.m_total_images; image_index++) - { - gpu_image_vec& gi = gpu_images[format_iter][image_index]; - - if (!gi.size()) - continue; - - uint32_t level; - for (level = 0; level < gi.size(); level++) - if (!gi[level].get_total_blocks()) - break; - - if (level < gi.size()) - continue; - - if ((!opts.m_no_ktx) && (fileinfo.m_tex_type != basist::cBASISTexTypeCubemapArray)) - { - std::string ktx_filename(base_filename + string_format("_transcoded_%s_%04u.ktx", basist::basis_get_format_name(transcoder_tex_fmt), image_index)); - if (!write_compressed_texture_file(ktx_filename.c_str(), gi)) - { - error_printf("Failed writing KTX file \"%s\"!\n", ktx_filename.c_str()); - return false; - } - printf("Wrote KTX file \"%s\"\n", ktx_filename.c_str()); - } - - for (uint32_t level_index = 0; level_index < gi.size(); level_index++) - { - basist::basisu_image_level_info level_info; - - if (!dec.get_image_level_info(&basis_data[0], (uint32_t)basis_data.size(), level_info, image_index, level_index)) - { - error_printf("Failed retrieving image level information (%u %u)!\n", image_index, level_index); - return false; - } - - image u; - if (!gi[level_index].unpack(u)) - { - printf("Warning: Failed unpacking GPU texture data (%u %u %u). Unpacking as much as possible.\n", format_iter, image_index, level_index); - total_unpack_warnings++; - } - //u.crop(level_info.m_orig_width, level_info.m_orig_height); - - std::string rgb_filename; - if (gi.size() > 1) - rgb_filename = base_filename + string_format("_unpacked_rgb_%s_%u_%04u.png", basist::basis_get_format_name(transcoder_tex_fmt), level_index, image_index); - else - rgb_filename = base_filename + string_format("_unpacked_rgb_%s_%04u.png", basist::basis_get_format_name(transcoder_tex_fmt), image_index); - if (!save_png(rgb_filename, u, cImageSaveIgnoreAlpha)) - { - error_printf("Failed writing to PNG file \"%s\"\n", rgb_filename.c_str()); - return false; - } - printf("Wrote PNG file \"%s\"\n", rgb_filename.c_str()); - - if (transcoder_tex_fmt == basist::transcoder_texture_format::cTFFXT1_RGB) - { - std::string out_filename; - if (gi.size() > 1) - out_filename = base_filename + string_format("_unpacked_rgb_%s_%u_%04u.out", basist::basis_get_format_name(transcoder_tex_fmt), level_index, image_index); - else - out_filename = base_filename + string_format("_unpacked_rgb_%s_%04u.out", basist::basis_get_format_name(transcoder_tex_fmt), image_index); - if (!write_3dfx_out_file(out_filename.c_str(), gi[level_index])) - { - error_printf("Failed writing to OUT file \"%s\"\n", out_filename.c_str()); - return false; - } - printf("Wrote .OUT file \"%s\"\n", out_filename.c_str()); - } - - if (basis_transcoder_format_has_alpha(transcoder_tex_fmt)) - { - std::string a_filename; - if (gi.size() > 1) - a_filename = base_filename + string_format("_unpacked_a_%s_%u_%04u.png", basist::basis_get_format_name(transcoder_tex_fmt), level_index, image_index); - else - a_filename = base_filename + string_format("_unpacked_a_%s_%04u.png", basist::basis_get_format_name(transcoder_tex_fmt), image_index); - if (!save_png(a_filename, u, cImageSaveGrayscale, 3)) - { - error_printf("Failed writing to PNG file \"%s\"\n", a_filename.c_str()); - return false; - } - printf("Wrote PNG file \"%s\"\n", a_filename.c_str()); - } - - } // level_index - - } // image_index - - } // format_iter - - } // if (!validate_flag) - - // Now unpack to RGBA using the transcoder itself to do the unpacking to raster images - for (uint32_t image_index = 0; image_index < fileinfo.m_total_images; image_index++) - { - for (uint32_t level_index = 0; level_index < fileinfo.m_image_mipmap_levels[image_index]; level_index++) - { - const basist::transcoder_texture_format transcoder_tex_fmt = basist::transcoder_texture_format::cTFRGBA32; - - basist::basisu_image_level_info level_info; - - if (!dec.get_image_level_info(&basis_data[0], (uint32_t)basis_data.size(), level_info, image_index, level_index)) - { - error_printf("Failed retrieving image level information (%u %u)!\n", image_index, level_index); - return false; - } - - image img(level_info.m_orig_width, level_info.m_orig_height); - - fill_buffer_with_random_bytes(&img(0, 0), img.get_total_pixels() * sizeof(uint32_t)); - - tm.start(); - - if (!dec.transcode_image_level(&basis_data[0], (uint32_t)basis_data.size(), image_index, level_index, &img(0, 0).r, img.get_total_pixels(), transcoder_tex_fmt, 0, img.get_pitch(), nullptr, img.get_height())) - { - error_printf("Failed transcoding image level (%u %u %u)!\n", image_index, level_index, transcoder_tex_fmt); - return false; - } - - double total_transcode_time = tm.get_elapsed_ms(); - - printf("Transcode of image %u level %u res %ux%u format %s succeeded in %3.3f ms\n", image_index, level_index, level_info.m_orig_width, level_info.m_orig_height, basist::basis_get_format_name(transcoder_tex_fmt), total_transcode_time); - - std::string rgb_filename(base_filename + string_format("_unpacked_rgb_%s_%u_%04u.png", basist::basis_get_format_name(transcoder_tex_fmt), level_index, image_index)); - if (!save_png(rgb_filename, img, cImageSaveIgnoreAlpha)) - { - error_printf("Failed writing to PNG file \"%s\"\n", rgb_filename.c_str()); - return false; - } - printf("Wrote PNG file \"%s\"\n", rgb_filename.c_str()); - - std::string a_filename(base_filename + string_format("_unpacked_a_%s_%u_%04u.png", basist::basis_get_format_name(transcoder_tex_fmt), level_index, image_index)); - if (!save_png(a_filename, img, cImageSaveGrayscale, 3)) - { - error_printf("Failed writing to PNG file \"%s\"\n", a_filename.c_str()); - return false; - } - printf("Wrote PNG file \"%s\"\n", a_filename.c_str()); - - } // level_index - } // image_index - - // Now unpack to RGB565 using the transcoder itself to do the unpacking to raster images - for (uint32_t image_index = 0; image_index < fileinfo.m_total_images; image_index++) - { - for (uint32_t level_index = 0; level_index < fileinfo.m_image_mipmap_levels[image_index]; level_index++) - { - const basist::transcoder_texture_format transcoder_tex_fmt = basist::transcoder_texture_format::cTFRGB565; - - basist::basisu_image_level_info level_info; - - if (!dec.get_image_level_info(&basis_data[0], (uint32_t)basis_data.size(), level_info, image_index, level_index)) - { - error_printf("Failed retrieving image level information (%u %u)!\n", image_index, level_index); - return false; - } - - std::vector<uint16_t> packed_img(level_info.m_orig_width * level_info.m_orig_height); - - fill_buffer_with_random_bytes(&packed_img[0], packed_img.size() * sizeof(uint16_t)); - - tm.start(); - - if (!dec.transcode_image_level(&basis_data[0], (uint32_t)basis_data.size(), image_index, level_index, &packed_img[0], (uint32_t)packed_img.size(), transcoder_tex_fmt, 0, level_info.m_orig_width, nullptr, level_info.m_orig_height)) - { - error_printf("Failed transcoding image level (%u %u %u)!\n", image_index, level_index, transcoder_tex_fmt); - return false; - } - - double total_transcode_time = tm.get_elapsed_ms(); - - image img(level_info.m_orig_width, level_info.m_orig_height); - for (uint32_t y = 0; y < level_info.m_orig_height; y++) - { - for (uint32_t x = 0; x < level_info.m_orig_width; x++) - { - const uint16_t p = packed_img[x + y * level_info.m_orig_width]; - uint32_t r = p >> 11, g = (p >> 5) & 63, b = p & 31; - r = (r << 3) | (r >> 2); - g = (g << 2) | (g >> 4); - b = (b << 3) | (b >> 2); - img(x, y).set(r, g, b, 255); - } - } - - printf("Transcode of image %u level %u res %ux%u format %s succeeded in %3.3f ms\n", image_index, level_index, level_info.m_orig_width, level_info.m_orig_height, basist::basis_get_format_name(transcoder_tex_fmt), total_transcode_time); - - std::string rgb_filename(base_filename + string_format("_unpacked_rgb_%s_%u_%04u.png", basist::basis_get_format_name(transcoder_tex_fmt), level_index, image_index)); - if (!save_png(rgb_filename, img, cImageSaveIgnoreAlpha)) - { - error_printf("Failed writing to PNG file \"%s\"\n", rgb_filename.c_str()); - return false; - } - printf("Wrote PNG file \"%s\"\n", rgb_filename.c_str()); - - } // level_index - } // image_index - - // Now unpack to RGBA4444 using the transcoder itself to do the unpacking to raster images - for (uint32_t image_index = 0; image_index < fileinfo.m_total_images; image_index++) - { - for (uint32_t level_index = 0; level_index < fileinfo.m_image_mipmap_levels[image_index]; level_index++) - { - const basist::transcoder_texture_format transcoder_tex_fmt = basist::transcoder_texture_format::cTFRGBA4444; - - basist::basisu_image_level_info level_info; - - if (!dec.get_image_level_info(&basis_data[0], (uint32_t)basis_data.size(), level_info, image_index, level_index)) - { - error_printf("Failed retrieving image level information (%u %u)!\n", image_index, level_index); - return false; - } - - std::vector<uint16_t> packed_img(level_info.m_orig_width * level_info.m_orig_height); - - fill_buffer_with_random_bytes(&packed_img[0], packed_img.size() * sizeof(uint16_t)); - - tm.start(); - - if (!dec.transcode_image_level(&basis_data[0], (uint32_t)basis_data.size(), image_index, level_index, &packed_img[0], (uint32_t)packed_img.size(), transcoder_tex_fmt, 0, level_info.m_orig_width, nullptr, level_info.m_orig_height)) - { - error_printf("Failed transcoding image level (%u %u %u)!\n", image_index, level_index, transcoder_tex_fmt); - return false; - } - - double total_transcode_time = tm.get_elapsed_ms(); - - image img(level_info.m_orig_width, level_info.m_orig_height); - for (uint32_t y = 0; y < level_info.m_orig_height; y++) - { - for (uint32_t x = 0; x < level_info.m_orig_width; x++) - { - const uint16_t p = packed_img[x + y * level_info.m_orig_width]; - uint32_t r = p >> 12, g = (p >> 8) & 15, b = (p >> 4) & 15, a = p & 15; - r = (r << 4) | r; - g = (g << 4) | g; - b = (b << 4) | b; - a = (a << 4) | a; - img(x, y).set(r, g, b, a); - } - } - - printf("Transcode of image %u level %u res %ux%u format %s succeeded in %3.3f ms\n", image_index, level_index, level_info.m_orig_width, level_info.m_orig_height, basist::basis_get_format_name(transcoder_tex_fmt), total_transcode_time); - - std::string rgb_filename(base_filename + string_format("_unpacked_rgb_%s_%u_%04u.png", basist::basis_get_format_name(transcoder_tex_fmt), level_index, image_index)); - if (!save_png(rgb_filename, img, cImageSaveIgnoreAlpha)) - { - error_printf("Failed writing to PNG file \"%s\"\n", rgb_filename.c_str()); - return false; - } - printf("Wrote PNG file \"%s\"\n", rgb_filename.c_str()); - - std::string a_filename(base_filename + string_format("_unpacked_a_%s_%u_%04u.png", basist::basis_get_format_name(transcoder_tex_fmt), level_index, image_index)); - if (!save_png(a_filename, img, cImageSaveGrayscale, 3)) - { - error_printf("Failed writing to PNG file \"%s\"\n", a_filename.c_str()); - return false; - } - printf("Wrote PNG file \"%s\"\n", a_filename.c_str()); - - } // level_index - } // image_index - - } // file_index - - if (total_pvrtc_nonpow2_warnings) - printf("Warning: %u images could not be transcoded to PVRTC1 because one or both dimensions were not a power of 2\n", total_pvrtc_nonpow2_warnings); - - if (total_unpack_warnings) - printf("ATTENTION: %u total images had invalid GPU texture data!\n", total_unpack_warnings); - else - printf("Success\n"); - - return true; -} - -static bool compare_mode(command_line_params &opts) -{ - if (opts.m_input_filenames.size() != 2) - { - error_printf("Must specify two PNG filenames using -file\n"); - return false; - } - - image a, b; - if (!load_png(opts.m_input_filenames[0].c_str(), a)) - { - error_printf("Failed loading image from file \"%s\"!\n", opts.m_input_filenames[0].c_str()); - return false; - } - - printf("Loaded \"%s\", %ux%u, has alpha: %u\n", opts.m_input_filenames[0].c_str(), a.get_width(), a.get_height(), a.has_alpha()); - - if (!load_png(opts.m_input_filenames[1].c_str(), b)) - { - error_printf("Failed loading image from file \"%s\"!\n", opts.m_input_filenames[1].c_str()); - return false; - } - - printf("Loaded \"%s\", %ux%u, has alpha: %u\n", opts.m_input_filenames[1].c_str(), b.get_width(), b.get_height(), b.has_alpha()); - - if ((a.get_width() != b.get_width()) || (a.get_height() != b.get_height())) - { - printf("Images don't have the same dimensions - cropping input images to smallest common dimensions\n"); - - uint32_t w = minimum(a.get_width(), b.get_width()); - uint32_t h = minimum(a.get_height(), b.get_height()); - - a.crop(w, h); - b.crop(w, h); - } - - printf("Comparison image res: %ux%u\n", a.get_width(), a.get_height()); - - image_metrics im; - im.calc(a, b, 0, 3); - im.print("RGB "); - - im.calc(a, b, 0, 1); - im.print("R "); - - im.calc(a, b, 1, 1); - im.print("G "); - - im.calc(a, b, 2, 1); - im.print("B "); - - im.calc(a, b, 0, 0); - im.print("Y 709 " ); - - im.calc(a, b, 0, 0, true, true); - im.print("Y 601 " ); - - if (opts.m_compare_ssim) - { - vec4F s_rgb(compute_ssim(a, b, false, false)); - - printf("R SSIM: %f\n", s_rgb[0]); - printf("G SSIM: %f\n", s_rgb[1]); - printf("B SSIM: %f\n", s_rgb[2]); - printf("RGB Avg SSIM: %f\n", (s_rgb[0] + s_rgb[1] + s_rgb[2]) / 3.0f); - printf("A SSIM: %f\n", s_rgb[3]); - - vec4F s_y_709(compute_ssim(a, b, true, false)); - printf("Y 709 SSIM: %f\n", s_y_709[0]); - - vec4F s_y_601(compute_ssim(a, b, true, true)); - printf("Y 601 SSIM: %f\n", s_y_601[0]); - } - - image delta_img(a.get_width(), a.get_height()); - - const int X = 2; - - for (uint32_t y = 0; y < a.get_height(); y++) - { - for (uint32_t x = 0; x < a.get_width(); x++) - { - color_rgba &d = delta_img(x, y); - - for (int c = 0; c < 4; c++) - d[c] = (uint8_t)clamp<int>((a(x, y)[c] - b(x, y)[c]) * X + 128, 0, 255); - } // x - } // y - - save_png("a_rgb.png", a, cImageSaveIgnoreAlpha); - save_png("a_alpha.png", a, cImageSaveGrayscale, 3); - printf("Wrote a_rgb.png and a_alpha.png\n"); - - save_png("b_rgb.png", b, cImageSaveIgnoreAlpha); - save_png("b_alpha.png", b, cImageSaveGrayscale, 3); - printf("Wrote b_rgb.png and b_alpha.png\n"); - - save_png("delta_img_rgb.png", delta_img, cImageSaveIgnoreAlpha); - printf("Wrote delta_img_rgb.png\n"); - - save_png("delta_img_a.png", delta_img, cImageSaveGrayscale, 3); - printf("Wrote delta_img_a.png\n"); - - return true; -} - -static int main_internal(int argc, const char **argv) -{ - printf("Basis Universal GPU Texture Compressor Reference Encoder v" BASISU_TOOL_VERSION ", Copyright (C) 2019 Binomial LLC, All rights reserved\n"); - - //interval_timer tm; - //tm.start(); - - basisu_encoder_init(); - - //printf("Encoder and transcoder libraries initialized in %3.3f ms\n", tm.get_elapsed_ms()); - -#if defined(DEBUG) || defined(_DEBUG) - printf("DEBUG build\n"); -#endif - - if (argc == 1) - { - print_usage(); - return EXIT_FAILURE; - } - - command_line_params opts; - if (!opts.parse(argc, argv)) - { - print_usage(); - return EXIT_FAILURE; - } - - if (!opts.process_listing_files()) - return EXIT_FAILURE; - - if (opts.m_mode == cDefault) - { - for (size_t i = 0; i < opts.m_input_filenames.size(); i++) - { - std::string ext(string_get_extension(opts.m_input_filenames[i])); - if (strcasecmp(ext.c_str(), "basis") == 0) - { - // If they haven't specified any modes, and they give us a .basis file, then assume they want to unpack it. - opts.m_mode = cUnpack; - break; - } - } - } - - bool status = false; - - switch (opts.m_mode) - { - case cDefault: - case cCompress: - status = compress_mode(opts); - break; - case cValidate: - status = unpack_and_validate_mode(opts, true); - break; - case cUnpack: - status = unpack_and_validate_mode(opts, false); - break; - case cCompare: - status = compare_mode(opts); - break; - case cVersion: - status = true; // We printed the version at the beginning of main_internal - break; - default: - assert(0); - break; - } - - return status ? EXIT_SUCCESS : EXIT_FAILURE; -} - -int main(int argc, const char **argv) -{ - int status = EXIT_FAILURE; - -#if BASISU_CATCH_EXCEPTIONS - try - { - status = main_internal(argc, argv); - } - catch (const std::exception &exc) - { - fprintf(stderr, "Fatal error: Caught exception \"%s\"\n", exc.what()); - } - catch (...) - { - fprintf(stderr, "Fatal error: Uncaught exception!\n"); - } -#else - status = main_internal(argc, argv); -#endif - - return status; -} |