From 6e9b5225d27d10f3d83e35928454b8cea0b64d60 Mon Sep 17 00:00:00 2001 From: W2Wizard Date: Sat, 17 Apr 2021 20:08:10 +0200 Subject: [PATCH 01/12] Add init functions --- Source/Engine/Core/Collections/Array.h | 32 ++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Source/Engine/Core/Collections/Array.h b/Source/Engine/Core/Collections/Array.h index 6a841bac5..cc8bcf6e0 100644 --- a/Source/Engine/Core/Collections/Array.h +++ b/Source/Engine/Core/Collections/Array.h @@ -47,6 +47,20 @@ public: _allocation.Allocate(capacity); } + /// + /// Initializes a new instance of the class. + /// + /// The initial values defined in the array. + Array(std::initializer_list initList) + { + _count = _capacity = (int32)initList.size(); + if (_count > 0) + { + _allocation.Allocate(_count); + Memory::ConstructItems(Get(), initList.begin(), _count); + } + } + /// /// Initializes a new instance of the class. /// @@ -123,6 +137,24 @@ public: _allocation.Swap(other._allocation); } + /// + /// The assignment operator that deletes the current collection of items and the copies items from the initializer list. + /// + /// The other collection to copy. + /// The reference to this. + Array& operator=(std::initializer_list initList) noexcept + { + Memory::DestructItems(Get(), _count); + + _count = _capacity = (int32)initList.size(); + if (_capacity > 0) + { + _allocation.Allocate(_capacity); + Memory::ConstructItems(Get(), initList.begin(), _count); + } + return *this; + } + /// /// The assignment operator that deletes the current collection of items and the copies items from the other array. /// From b1ad70b6b250185b1d591e8cf61a985ef564a804 Mon Sep 17 00:00:00 2001 From: "W2.Wizard" Date: Sat, 3 Apr 2021 00:58:22 +0200 Subject: [PATCH 02/12] Add include --- Source/Engine/Core/Collections/Array.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Engine/Core/Collections/Array.h b/Source/Engine/Core/Collections/Array.h index cc8bcf6e0..3819323a9 100644 --- a/Source/Engine/Core/Collections/Array.h +++ b/Source/Engine/Core/Collections/Array.h @@ -2,6 +2,7 @@ #pragma once +#include #include "Engine/Platform/Platform.h" #include "Engine/Core/Memory/Memory.h" #include "Engine/Core/Memory/Allocation.h" From 6821e3c3703eff0b3059f9bf999b5a27c718ad35 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 22 Apr 2021 19:25:01 +0200 Subject: [PATCH 03/12] Fix progress bar drawing precision and stability #471 --- Source/Engine/UI/GUI/Common/ProgressBar.cs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/Source/Engine/UI/GUI/Common/ProgressBar.cs b/Source/Engine/UI/GUI/Common/ProgressBar.cs index 21cce7faa..881bbc161 100644 --- a/Source/Engine/UI/GUI/Common/ProgressBar.cs +++ b/Source/Engine/UI/GUI/Common/ProgressBar.cs @@ -39,9 +39,6 @@ namespace FlaxEngine.GUI /// /// Gets a value indicating whether use progress value smoothing. /// - /// - /// true if use progress value smoothing; otherwise, false. - /// public bool UseSmoothing => !Mathf.IsZero(SmoothingScale); /// @@ -91,8 +88,6 @@ namespace FlaxEngine.GUI if (!Mathf.NearEqual(value, _value)) { _value = value; - - // Check if skip smoothing if (!UseSmoothing) { _current = _value; @@ -138,22 +133,22 @@ namespace FlaxEngine.GUI /// public override void Update(float deltaTime) { - bool isDeltaSlow = deltaTime > (1 / 20.0f); - - // Ensure progress bar is visible if (Visible) { // Value smoothing + var value = _value; if (Mathf.Abs(_current - _value) > 0.01f) { // Lerp or not if running slow - float value; + bool isDeltaSlow = deltaTime > (1 / 20.0f); if (!isDeltaSlow && UseSmoothing) value = Mathf.Lerp(_current, _value, Mathf.Saturate(deltaTime * 5.0f * SmoothingScale)); - else - value = _value; _current = value; } + else + { + _current = _value; + } } base.Update(deltaTime); From 3e945fbe34be503675bdd8915305541da56c9163 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 22 Apr 2021 20:24:21 +0200 Subject: [PATCH 04/12] Bump up version number --- Flax.flaxproj | 2 +- Source/FlaxEngine.Gen.cs | 4 ++-- Source/FlaxEngine.Gen.h | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Flax.flaxproj b/Flax.flaxproj index cc643346f..681c1dc55 100644 --- a/Flax.flaxproj +++ b/Flax.flaxproj @@ -3,7 +3,7 @@ "Version": { "Major": 1, "Minor": 1, - "Build": 6217 + "Build": 6218 }, "Company": "Flax", "Copyright": "Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.", diff --git a/Source/FlaxEngine.Gen.cs b/Source/FlaxEngine.Gen.cs index 6f8878d25..62d40ad9a 100644 --- a/Source/FlaxEngine.Gen.cs +++ b/Source/FlaxEngine.Gen.cs @@ -13,5 +13,5 @@ using System.Runtime.InteropServices; [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] [assembly: Guid("b8442186-4a70-7c85-704a-857c262d00f6")] -[assembly: AssemblyVersion("1.1.6217")] -[assembly: AssemblyFileVersion("1.1.6217")] +[assembly: AssemblyVersion("1.1.6218")] +[assembly: AssemblyFileVersion("1.1.6218")] diff --git a/Source/FlaxEngine.Gen.h b/Source/FlaxEngine.Gen.h index 7a888ae1f..eff8449cc 100644 --- a/Source/FlaxEngine.Gen.h +++ b/Source/FlaxEngine.Gen.h @@ -3,11 +3,11 @@ #pragma once #define FLAXENGINE_NAME "FlaxEngine" -#define FLAXENGINE_VERSION Version(1, 1, 6217) -#define FLAXENGINE_VERSION_TEXT "1.1.6217" +#define FLAXENGINE_VERSION Version(1, 1, 6218) +#define FLAXENGINE_VERSION_TEXT "1.1.6218" #define FLAXENGINE_VERSION_MAJOR 1 #define FLAXENGINE_VERSION_MINOR 1 -#define FLAXENGINE_VERSION_BUILD 6217 +#define FLAXENGINE_VERSION_BUILD 6218 #define FLAXENGINE_COMPANY "Flax" #define FLAXENGINE_COPYRIGHT "Copyright (c) 2012-2021 Wojciech Figat. All rights reserved." From 2b698ca8b03f8c7894faca9019c0201270982408 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 22 Apr 2021 21:03:40 +0200 Subject: [PATCH 05/12] Add support for fixed-array fields in scripting --- Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs | 8 +++++++- Source/Tools/Flax.Build/Bindings/BindingsGenerator.cs | 3 --- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs index 5f74e0403..6828a8eca 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs @@ -1252,7 +1252,13 @@ namespace Flax.Build.Bindings if (fieldInfo.Getter != null) GenerateCppWrapperFunction(buildData, contents, classInfo, fieldInfo.Getter, "{0}"); if (fieldInfo.Setter != null) - GenerateCppWrapperFunction(buildData, contents, classInfo, fieldInfo.Setter, "{0} = {1}"); + { + var callFormat = "{0} = {1}"; + var type = fieldInfo.Setter.Parameters[0].Type; + if (type.IsArray) + callFormat = $"auto __tmp = {{1}}; for (int32 i = 0; i < {type.ArraySize}; i++) {{0}}[i] = __tmp[i]"; + GenerateCppWrapperFunction(buildData, contents, classInfo, fieldInfo.Setter, callFormat); + } } // Properties diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.cs index 742aa6f63..f8d26314f 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.cs @@ -623,9 +623,6 @@ namespace Flax.Build.Bindings if (!fieldInfo.IsReadOnly) { - if (fieldInfo.Type.IsArray) - throw new NotImplementedException("Use ReadOnly on field. TODO: add support for setter for fixed-array fields."); - fieldInfo.Setter = new FunctionInfo { Name = "Set" + fieldInfo.Name, From 27fbd896f7b2ac12b7bc8683bb24b3c229698596 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 23 Apr 2021 16:35:18 +0200 Subject: [PATCH 06/12] Fix Win32 stack traces issue due to invalid search path for debug symbols #457 --- .../Platform/Windows/WindowsPlatform.cpp | 90 ++++++------------- 1 file changed, 29 insertions(+), 61 deletions(-) diff --git a/Source/Engine/Platform/Windows/WindowsPlatform.cpp b/Source/Engine/Platform/Windows/WindowsPlatform.cpp index 1b8942dec..8bff48f18 100644 --- a/Source/Engine/Platform/Windows/WindowsPlatform.cpp +++ b/Source/Engine/Platform/Windows/WindowsPlatform.cpp @@ -38,7 +38,7 @@ namespace CriticalSection SymLocker; bool SymInitialized = false; bool SymModulesDirty = true; - char* SymPath = nullptr; + Array SymbolsPath; #endif } @@ -617,9 +617,8 @@ void WindowsPlatform::Exit() { SymInitialized = false; SymCleanup(GetCurrentProcess()); - free(SymPath); - SymPath = nullptr; } + SymbolsPath.Resize(0); SymLocker.Unlock(); #endif @@ -1116,7 +1115,13 @@ void* WindowsPlatform::LoadLibrary(const Char* filename) #if CRASH_LOG_ENABLE // Refresh modules info during next stack trace collecting to have valid debug symbols information SymLocker.Lock(); - SymModulesDirty = true; + const auto folder = StringUtils::GetDirectoryName(filename); + if (!SymbolsPath.Contains(folder)) + SymbolsPath.Add(folder); + if (SymInitialized) + { + SymModulesDirty = true; + } SymLocker.Unlock(); #endif @@ -1137,80 +1142,43 @@ Array WindowsPlatform::GetStackFrames(int32 skipCount, SymInitialized = true; // Build search path - const size_t nSymPathLen = 4096; - SymPath = (char*)malloc(nSymPathLen); - SymPath[0] = 0; - strcat_s(SymPath, nSymPathLen, ".;"); - const size_t nTempLen = 1024; - char szTemp[nTempLen]; - - // Current directory path - if (GetCurrentDirectoryA(nTempLen, szTemp) > 0) + String symbolSearchPath; + TCHAR ModulePath[MAX_PATH] = { 0 }; + if (::GetModuleFileName(::GetModuleHandle(nullptr), ModulePath, MAX_PATH)) { - szTemp[nTempLen - 1] = 0; - strcat_s(SymPath, nSymPathLen, szTemp); - strcat_s(SymPath, nSymPathLen, ";"); + symbolSearchPath += StringUtils::GetDirectoryName(ModulePath); + symbolSearchPath += ";"; } - - // Main module path - if (GetModuleFileNameA(nullptr, szTemp, nTempLen) > 0) + for (auto& path : SymbolsPath) { - szTemp[nTempLen - 1] = 0; - for (char* p = (szTemp + strlen(szTemp) - 1); p >= szTemp; --p) - { - // Locate the rightmost path separator - if ((*p == '\\') || (*p == '/') || (*p == ':')) - { - *p = 0; - break; - } - } - if (strlen(szTemp) > 0) - { - strcat_s(SymPath, nSymPathLen, szTemp); - strcat_s(SymPath, nSymPathLen, ";"); - } + symbolSearchPath += path; + symbolSearchPath += ";"; } - - // System symbols paths - if (GetEnvironmentVariableA("_NT_SYMBOL_PATH", szTemp, nTempLen) > 0) + String _NT_SYMBOL_PATH; + if (!Platform::GetEnvironmentVariable(TEXT("_NT_SYMBOL_PATH"), _NT_SYMBOL_PATH)) { - szTemp[nTempLen - 1] = 0; - strcat_s(SymPath, nSymPathLen, szTemp); - strcat_s(SymPath, nSymPathLen, ";"); + symbolSearchPath += _NT_SYMBOL_PATH; + symbolSearchPath += ";"; } - if (GetEnvironmentVariableA("_NT_ALTERNATE_SYMBOL_PATH", szTemp, nTempLen) > 0) - { - szTemp[nTempLen - 1] = 0; - strcat_s(SymPath, nSymPathLen, szTemp); - strcat_s(SymPath, nSymPathLen, ";"); - } - if (GetEnvironmentVariableA("SYSTEMROOT", szTemp, nTempLen) > 0) - { - szTemp[nTempLen - 1] = 0; - strcat_s(SymPath, nSymPathLen, szTemp); - strcat_s(SymPath, nSymPathLen, ";"); - - strcat_s(szTemp, nTempLen, "\\system32"); - strcat_s(SymPath, nSymPathLen, szTemp); - strcat_s(SymPath, nSymPathLen, ";"); - } - - SymInitialize(process, SymPath, FALSE); + symbolSearchPath += Platform::GetWorkingDirectory(); + symbolSearchPath += ";"; DWORD options = SymGetOptions(); options |= SYMOPT_LOAD_LINES; options |= SYMOPT_FAIL_CRITICAL_ERRORS; + options |= SYMOPT_DEFERRED_LOADS; + options |= SYMOPT_EXACT_SYMBOLS; SymSetOptions(options); + + SymInitializeW(process, *symbolSearchPath, TRUE); } - // Load modules + // Refresh modules if needed if (SymModulesDirty) { SymModulesDirty = false; - GetModuleListPSAPI(process); + SymRefreshModuleList(process); } - SymRefreshModuleList(process); // Capture the context if missing /*EXCEPTION_POINTERS exceptionPointers; From 23e722a9fb059a892aa009c3c33359434f7526c4 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 23 Apr 2021 22:36:56 +0200 Subject: [PATCH 07/12] Add timeout check for drag&drop on Linux to prevent deadlock --- .../Engine/Platform/Linux/LinuxPlatform.cpp | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/Source/Engine/Platform/Linux/LinuxPlatform.cpp b/Source/Engine/Platform/Linux/LinuxPlatform.cpp index 95426b70a..59066a2e7 100644 --- a/Source/Engine/Platform/Linux/LinuxPlatform.cpp +++ b/Source/Engine/Platform/Linux/LinuxPlatform.cpp @@ -1382,6 +1382,7 @@ DragDropEffect LinuxWindow::DoDragDrop(const StringView& data) X11::Window previousWindow = 0; DragDropEffect result = DragDropEffect::None; float lastDraw = Platform::GetTimeSeconds(); + float startTime = lastDraw; while (true) { X11::XNextEvent(xDisplay, &event); @@ -1559,7 +1560,7 @@ DragDropEffect LinuxWindow::DoDragDrop(const StringView& data) if (!(event.xclient.data.l[1]&1) && status != Unaware) status = Unreceptive; } - else if (event.type == ButtonRelease && event.xbutton.button == 1) + else if (event.type == ButtonRelease && event.xbutton.button == Button1) { if (status == CanDrop) { @@ -1597,11 +1598,46 @@ DragDropEffect LinuxWindow::DoDragDrop(const StringView& data) // Redraw const float time = Platform::GetTimeSeconds(); - if (time - lastDraw >= 1.0f / 60.0f) + if (time - lastDraw >= 1.0f / 20.0f) { lastDraw = time; Engine::OnDraw(); } + + // Prevent dead-loop + if (time - startTime >= 10.0f) + { + break; + } + } + + // Drag end + if (previousWindow != 0 && previousVersion != -1) + { + // Send drag left event + auto ww = WindowsManager::GetByNativePtr((void*)previousWindow); + if (ww) + { + ww->_dragOver = false; + ww->OnDragLeave(); + } + else + { + X11::XClientMessageEvent m; + memset(&m, 0, sizeof(m)); + m.type = ClientMessage; + m.display = event.xclient.display; + m.window = previousWindow; + m.message_type = xAtomXdndLeave; + m.format = 32; + m.data.l[0] = _window; + m.data.l[1] = 0; + m.data.l[2] = 0; + m.data.l[3] = 0; + m.data.l[4] = 0; + X11::XSendEvent(xDisplay, previousWindow, 0, NoEventMask, (X11::XEvent*)&m); + X11::XFlush(xDisplay); + } } // End grabbing From 35f06bbf6e2d81ce565b65003109799f4357a461 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 26 Apr 2021 15:15:17 +0200 Subject: [PATCH 08/12] Fix using TextBoxBase with child controls (cherry picked from commit 2b41c8d24f269ce3a1a0e04bae7da4bca22ea2b4) --- Source/Engine/UI/GUI/Common/TextBoxBase.cs | 28 +++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/Source/Engine/UI/GUI/Common/TextBoxBase.cs b/Source/Engine/UI/GUI/Common/TextBoxBase.cs index 2e4ef51e3..162e220d7 100644 --- a/Source/Engine/UI/GUI/Common/TextBoxBase.cs +++ b/Source/Engine/UI/GUI/Common/TextBoxBase.cs @@ -279,10 +279,11 @@ namespace FlaxEngine.GUI } /// - /// Sets the text. + /// Sets the text (forced, even if user is editing it). /// /// The value. - protected void SetText(string value) + [NoAnimate] + public void SetText(string value) { // Prevent from null problems if (value == null) @@ -314,6 +315,18 @@ namespace FlaxEngine.GUI } } + /// + /// Sets the text as it was entered by user (focus, change value, defocus). + /// + /// The value. + [NoAnimate] + public void SetTextAsUser(string value) + { + Focus(); + SetText(value); + Defocus(); + } + /// /// Gets length of the text /// @@ -1000,7 +1013,8 @@ namespace FlaxEngine.GUI /// public override void OnMouseMove(Vector2 location) { - // Check if user is selecting + base.OnMouseMove(location); + if (_isSelecting) { // Find char index at current mouse location @@ -1014,6 +1028,9 @@ namespace FlaxEngine.GUI /// public override bool OnMouseDown(Vector2 location, MouseButton button) { + if (base.OnMouseDown(location, button)) + return true; + if (button == MouseButton.Left && _text.Length > 0) { Focus(); @@ -1050,6 +1067,9 @@ namespace FlaxEngine.GUI /// public override bool OnMouseUp(Vector2 location, MouseButton button) { + if (base.OnMouseUp(location, button)) + return true; + if (button == MouseButton.Left) { OnSelectingEnd(); @@ -1079,6 +1099,8 @@ namespace FlaxEngine.GUI /// public override bool OnCharInput(char c) { + if (base.OnCharInput(c)) + return true; Insert(c); return true; } From 59af92bfc400e11912ec149d5a3f0f59ba59b5d2 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 27 Apr 2021 10:57:07 +0200 Subject: [PATCH 09/12] Fix format string errors assertions into soft checks (cherry picked from commit c01e5efe439daed67e7caf30277a2d19bd1b43be) --- Source/ThirdParty/fmt/core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/ThirdParty/fmt/core.h b/Source/ThirdParty/fmt/core.h index e109ecbd4..77b113a0a 100644 --- a/Source/ThirdParty/fmt/core.h +++ b/Source/ThirdParty/fmt/core.h @@ -22,7 +22,7 @@ #define FMT_ASSERT(condition, message) \ if (!(condition)) \ { \ - Platform::Assert(message, __FILE__, __LINE__); \ + Platform::CheckFailed(message, __FILE__, __LINE__); \ } #else #define FMT_ASSERT(condition, message) ((void)0) From df1dfbec36446ea89eb3f8fdfd055256969b3f86 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 16 Apr 2021 15:47:26 +0200 Subject: [PATCH 10/12] Add support for object reference wrappers usage in hash maps and dictionaries (cherry picked from commit eab3631c334ce31038ee6eea8d72cea52635bb00) --- Source/Engine/Content/AssetReference.h | 6 ++++++ Source/Engine/Content/WeakAssetReference.h | 6 ++++++ Source/Engine/Scripting/ScriptingObjectReference.h | 6 ++++++ Source/Engine/Scripting/SoftObjectReference.h | 6 ++++++ 4 files changed, 24 insertions(+) diff --git a/Source/Engine/Content/AssetReference.h b/Source/Engine/Content/AssetReference.h index 40f57337d..0956e82be 100644 --- a/Source/Engine/Content/AssetReference.h +++ b/Source/Engine/Content/AssetReference.h @@ -274,3 +274,9 @@ public: OnSet(asset); } }; + +template +uint32 GetHash(const AssetReference& key) +{ + return GetHash(key.GetID()); +} diff --git a/Source/Engine/Content/WeakAssetReference.h b/Source/Engine/Content/WeakAssetReference.h index 4943fd0b5..49401bf25 100644 --- a/Source/Engine/Content/WeakAssetReference.h +++ b/Source/Engine/Content/WeakAssetReference.h @@ -229,3 +229,9 @@ public: OnSet(asset); } }; + +template +uint32 GetHash(const WeakAssetReference& key) +{ + return GetHash(key.GetID()); +} diff --git a/Source/Engine/Scripting/ScriptingObjectReference.h b/Source/Engine/Scripting/ScriptingObjectReference.h index eeed0dcc4..fd132d308 100644 --- a/Source/Engine/Scripting/ScriptingObjectReference.h +++ b/Source/Engine/Scripting/ScriptingObjectReference.h @@ -318,3 +318,9 @@ public: OnSet(object); } }; + +template +uint32 GetHash(const ScriptingObjectReference& key) +{ + return GetHash(key.GetID()); +} diff --git a/Source/Engine/Scripting/SoftObjectReference.h b/Source/Engine/Scripting/SoftObjectReference.h index b6f08db4a..e03ee81d0 100644 --- a/Source/Engine/Scripting/SoftObjectReference.h +++ b/Source/Engine/Scripting/SoftObjectReference.h @@ -326,3 +326,9 @@ public: OnSet(object); } }; + +template +uint32 GetHash(const SoftObjectReference& key) +{ + return GetHash(key.GetID()); +} From 801587ab6c6bcb52710c3fae136985aad7bd95eb Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 15 Apr 2021 16:56:07 +0200 Subject: [PATCH 11/12] Fix case sensitivity check for `StartsWith` and `EndsWith` in `StringView` (cherry picked from commit 752e7e73bc63b5ace47e588d1acbbe9d6be72d66) --- Source/Engine/Core/Types/StringView.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Engine/Core/Types/StringView.h b/Source/Engine/Core/Types/StringView.h index b413ff552..bbfdbccd7 100644 --- a/Source/Engine/Core/Types/StringView.h +++ b/Source/Engine/Core/Types/StringView.h @@ -160,16 +160,16 @@ public: { const int32 length = Length(); if (searchCase == StringSearchCase::IgnoreCase) - return length > 0 && _data[0] == c; - return length > 0 && StringUtils::ToLower(_data[0]) == StringUtils::ToLower(c); + return length > 0 && StringUtils::ToLower(_data[0]) == StringUtils::ToLower(c); + return length > 0 && _data[0] == c; } bool EndsWith(T c, StringSearchCase searchCase = StringSearchCase::IgnoreCase) const { const int32 length = Length(); if (searchCase == StringSearchCase::IgnoreCase) - return length > 0 && _data[length - 1] == c; - return length > 0 && StringUtils::ToLower(_data[length - 1]) == StringUtils::ToLower(c); + return length > 0 && StringUtils::ToLower(_data[length - 1]) == StringUtils::ToLower(c); + return length > 0 && _data[length - 1] == c; } bool StartsWith(const StringViewBase& prefix, StringSearchCase searchCase = StringSearchCase::IgnoreCase) const From b96f0efd9c6be19917fb02bbcc0122067f4228ee Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 14 Apr 2021 12:23:50 +0200 Subject: [PATCH 12/12] Fix using `Delegate<>` in API event (cherry picked from commit 7b2c034fba11573ebf56a20ee98d85e52bf03296) --- Source/Engine/Core/Delegate.h | 5 ----- Source/Engine/Core/Types/BaseTypes.h | 4 ++++ Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs | 2 ++ Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs | 3 ++- .../Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs | 4 +++- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Source/Engine/Core/Delegate.h b/Source/Engine/Core/Delegate.h index d4118c3da..17c0c6afe 100644 --- a/Source/Engine/Core/Delegate.h +++ b/Source/Engine/Core/Delegate.h @@ -4,11 +4,6 @@ #include "Engine/Core/Memory/Allocation.h" -template -class Function; -template -class Delegate; - /// /// The function object. /// diff --git a/Source/Engine/Core/Types/BaseTypes.h b/Source/Engine/Core/Types/BaseTypes.h index b57f139ff..90ad934c2 100644 --- a/Source/Engine/Core/Types/BaseTypes.h +++ b/Source/Engine/Core/Types/BaseTypes.h @@ -97,6 +97,10 @@ template class Pair; template class Dictionary; +template +class Function; +template +class Delegate; // Declares full set of operators for the enum type (using binary operation on integer values) #define DECLARE_ENUM_OPERATORS(T) \ diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs index ed07e1abd..7d61e74f6 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs @@ -136,6 +136,8 @@ namespace Flax.Build.Bindings private static string GenerateCSharpNativeToManaged(BuildData buildData, TypeInfo typeInfo, ApiTypeInfo caller) { string result; + if (typeInfo?.Type == null) + throw new ArgumentNullException(); // Use dynamic array as wrapper container for fixed-size native arrays if (typeInfo.IsArray) diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs index 6828a8eca..04ba431d8 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs @@ -1131,6 +1131,7 @@ namespace Flax.Build.Bindings // C# event invoking wrapper (calls C# event from C++ delegate) CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MClass.h"); CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MEvent.h"); + CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MClass.h"); contents.Append(" "); if (eventInfo.IsStatic) contents.Append("static "); @@ -1145,7 +1146,7 @@ namespace Flax.Build.Bindings contents.Append(" {").AppendLine(); contents.Append(" static MMethod* mmethod = nullptr;").AppendLine(); contents.Append(" if (!mmethod)").AppendLine(); - contents.AppendFormat(" mmethod = {1}::GetStaticClass()->GetMethod(\"Internal_{0}_Invoke\", {2});", eventInfo.Name, classTypeNameNative, paramsCount).AppendLine(); + contents.AppendFormat(" mmethod = {1}::TypeInitializer.GetType().ManagedClass->GetMethod(\"Internal_{0}_Invoke\", {2});", eventInfo.Name, classTypeNameNative, paramsCount).AppendLine(); contents.Append(" CHECK(mmethod);").AppendLine(); contents.Append(" MonoObject* exception = nullptr;").AppendLine(); if (paramsCount == 0) diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs index 7714e6abd..c7ef8ff59 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs @@ -213,7 +213,9 @@ namespace Flax.Build.Bindings type.GenericArgs = new List(); do { - type.GenericArgs.Add(ParseType(ref context)); + var argType = ParseType(ref context); + if (argType.Type != null) + type.GenericArgs.Add(argType); token = context.Tokenizer.NextToken(); } while (token.Type != TokenType.RightAngleBracket);