Merge remote-tracking branch 'origin/master' into 1.7
This commit is contained in:
@@ -205,8 +205,6 @@ void MaterialInstance::Bind(BindParameters& params)
|
||||
|
||||
Asset::LoadResult MaterialInstance::load()
|
||||
{
|
||||
ASSERT(_baseMaterial == nullptr);
|
||||
|
||||
// Get main chunk
|
||||
auto chunk0 = GetChunk(0);
|
||||
if (chunk0 == nullptr || chunk0->IsMissing())
|
||||
@@ -229,6 +227,7 @@ Asset::LoadResult MaterialInstance::load()
|
||||
else
|
||||
{
|
||||
// Clear parameters if has no material loaded
|
||||
_baseMaterial = nullptr;
|
||||
Params.Dispose();
|
||||
ParamsChanged();
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ void String::Set(const char* chars, int32 length)
|
||||
}
|
||||
_length = length;
|
||||
}
|
||||
if (chars)
|
||||
if (chars && length)
|
||||
StringUtils::ConvertANSI2UTF16(chars, _data, length, _length);
|
||||
}
|
||||
|
||||
@@ -298,8 +298,10 @@ String String::TrimTrailing() const
|
||||
end--;
|
||||
}
|
||||
|
||||
ASSERT_LOW_LAYER(end >= start);
|
||||
return Substring(start, end - start + 1);
|
||||
const int32 count = end - start + 1;
|
||||
if (start >= 0 && start + count <= Length() && count >= 0)
|
||||
return String(_data + start, count);
|
||||
return Empty;
|
||||
}
|
||||
|
||||
String& String::operator/=(const Char* str)
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace FlaxEngine.Interop
|
||||
public static class NativeToManaged
|
||||
{
|
||||
public static object ConvertToManaged(IntPtr unmanaged) => unmanaged == IntPtr.Zero ? null : ManagedHandle.FromIntPtr(unmanaged).Target;
|
||||
public static IntPtr ConvertToUnmanaged(object managed) => managed != null ? ManagedHandle.ToIntPtr(managed, GCHandleType.Weak) : IntPtr.Zero;
|
||||
|
||||
public static void Free(IntPtr unmanaged)
|
||||
{
|
||||
@@ -44,6 +45,7 @@ namespace FlaxEngine.Interop
|
||||
#endif
|
||||
public static class ManagedToNative
|
||||
{
|
||||
public static object ConvertToManaged(IntPtr unmanaged) => unmanaged == IntPtr.Zero ? null : ManagedHandle.FromIntPtr(unmanaged).Target;
|
||||
public static IntPtr ConvertToUnmanaged(object managed) => managed != null ? ManagedHandle.ToIntPtr(managed, GCHandleType.Weak) : IntPtr.Zero;
|
||||
|
||||
public static void Free(IntPtr unmanaged)
|
||||
@@ -147,29 +149,16 @@ namespace FlaxEngine.Interop
|
||||
#if FLAX_EDITOR
|
||||
[HideInEditor]
|
||||
#endif
|
||||
[CustomMarshaller(typeof(FlaxEngine.Object), MarshalMode.ManagedToUnmanagedIn, typeof(ObjectMarshaller.ManagedToNative))]
|
||||
[CustomMarshaller(typeof(FlaxEngine.Object), MarshalMode.UnmanagedToManagedOut, typeof(ObjectMarshaller.ManagedToNative))]
|
||||
[CustomMarshaller(typeof(FlaxEngine.Object), MarshalMode.ElementIn, typeof(ObjectMarshaller.ManagedToNative))]
|
||||
[CustomMarshaller(typeof(FlaxEngine.Object), MarshalMode.ManagedToUnmanagedOut, typeof(ObjectMarshaller.NativeToManaged))]
|
||||
[CustomMarshaller(typeof(FlaxEngine.Object), MarshalMode.UnmanagedToManagedIn, typeof(ObjectMarshaller.NativeToManaged))]
|
||||
[CustomMarshaller(typeof(FlaxEngine.Object), MarshalMode.ElementOut, typeof(ObjectMarshaller.NativeToManaged))]
|
||||
[CustomMarshaller(typeof(FlaxEngine.Object), MarshalMode.ManagedToUnmanagedIn, typeof(ObjectMarshaller))]
|
||||
[CustomMarshaller(typeof(FlaxEngine.Object), MarshalMode.UnmanagedToManagedOut, typeof(ObjectMarshaller))]
|
||||
[CustomMarshaller(typeof(FlaxEngine.Object), MarshalMode.ElementIn, typeof(ObjectMarshaller))]
|
||||
[CustomMarshaller(typeof(FlaxEngine.Object), MarshalMode.ManagedToUnmanagedOut, typeof(ObjectMarshaller))]
|
||||
[CustomMarshaller(typeof(FlaxEngine.Object), MarshalMode.UnmanagedToManagedIn, typeof(ObjectMarshaller))]
|
||||
[CustomMarshaller(typeof(FlaxEngine.Object), MarshalMode.ElementOut, typeof(ObjectMarshaller))]
|
||||
public static class ObjectMarshaller
|
||||
{
|
||||
#if FLAX_EDITOR
|
||||
[HideInEditor]
|
||||
#endif
|
||||
public static class NativeToManaged
|
||||
{
|
||||
public static FlaxEngine.Object ConvertToManaged(IntPtr unmanaged) => unmanaged != IntPtr.Zero ? Unsafe.As<FlaxEngine.Object>(ManagedHandle.FromIntPtr(unmanaged).Target) : null;
|
||||
}
|
||||
|
||||
#if FLAX_EDITOR
|
||||
[HideInEditor]
|
||||
#endif
|
||||
public static class ManagedToNative
|
||||
{
|
||||
public static IntPtr ConvertToUnmanaged(FlaxEngine.Object managed) => Unsafe.As<object>(managed) != null ? ManagedHandle.ToIntPtr(managed) : IntPtr.Zero;
|
||||
}
|
||||
public static FlaxEngine.Object ConvertToManaged(IntPtr unmanaged) => unmanaged != IntPtr.Zero ? Unsafe.As<FlaxEngine.Object>(ManagedHandle.FromIntPtr(unmanaged).Target) : null;
|
||||
public static IntPtr ConvertToUnmanaged(FlaxEngine.Object managed) => Unsafe.As<object>(managed) != null ? ManagedHandle.ToIntPtr(managed) : IntPtr.Zero;
|
||||
}
|
||||
|
||||
#if FLAX_EDITOR
|
||||
@@ -342,6 +331,7 @@ namespace FlaxEngine.Interop
|
||||
public static class NativeToManaged
|
||||
{
|
||||
public static Dictionary<T, U> ConvertToManaged(IntPtr unmanaged) => DictionaryMarshaller<T, U>.ToManaged(unmanaged);
|
||||
public static IntPtr ConvertToUnmanaged(Dictionary<T, U> managed) => DictionaryMarshaller<T, U>.ToNative(managed, GCHandleType.Weak);
|
||||
public static void Free(IntPtr unmanaged) => DictionaryMarshaller<T, U>.Free(unmanaged);
|
||||
}
|
||||
|
||||
@@ -350,8 +340,8 @@ namespace FlaxEngine.Interop
|
||||
#endif
|
||||
public static class ManagedToNative
|
||||
{
|
||||
public static Dictionary<T, U> ConvertToManaged(IntPtr unmanaged) => DictionaryMarshaller<T, U>.ToManaged(unmanaged);
|
||||
public static IntPtr ConvertToUnmanaged(Dictionary<T, U> managed) => DictionaryMarshaller<T, U>.ToNative(managed, GCHandleType.Weak);
|
||||
|
||||
public static void Free(IntPtr unmanaged)
|
||||
{
|
||||
//DictionaryMarshaller<T, U>.Free(unmanaged); // No need to free weak handles
|
||||
@@ -425,6 +415,28 @@ namespace FlaxEngine.Interop
|
||||
return new T[numElements];
|
||||
}
|
||||
|
||||
public static TUnmanagedElement* AllocateContainerForUnmanagedElements(T[] managed, out int numElements)
|
||||
{
|
||||
if (managed is null)
|
||||
{
|
||||
numElements = 0;
|
||||
return null;
|
||||
}
|
||||
numElements = managed.Length;
|
||||
(ManagedHandle managedArrayHandle, _) = ManagedArray.AllocatePooledArray<TUnmanagedElement>(managed.Length);
|
||||
return (TUnmanagedElement*)ManagedHandle.ToIntPtr(managedArrayHandle);
|
||||
}
|
||||
|
||||
public static ReadOnlySpan<T> GetManagedValuesSource(T[] managed) => managed;
|
||||
|
||||
public static Span<TUnmanagedElement> GetUnmanagedValuesDestination(TUnmanagedElement* unmanaged)
|
||||
{
|
||||
if (unmanaged == null)
|
||||
return Span<TUnmanagedElement>.Empty;
|
||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(new IntPtr(unmanaged)).Target);
|
||||
return managedArray.ToSpan<TUnmanagedElement>();
|
||||
}
|
||||
|
||||
public static Span<T> GetManagedValuesDestination(T[] managed) => managed;
|
||||
|
||||
public static ReadOnlySpan<TUnmanagedElement> GetUnmanagedValuesSource(TUnmanagedElement* unmanaged, int numElements)
|
||||
@@ -591,6 +603,7 @@ namespace FlaxEngine.Interop
|
||||
public static class NativeToManaged
|
||||
{
|
||||
public static string ConvertToManaged(IntPtr unmanaged) => ManagedString.ToManaged(unmanaged);
|
||||
public static unsafe IntPtr ConvertToUnmanaged(string managed) => managed == null ? IntPtr.Zero : ManagedHandle.ToIntPtr(managed, GCHandleType.Weak);
|
||||
public static void Free(IntPtr unmanaged) => ManagedString.Free(unmanaged);
|
||||
}
|
||||
|
||||
@@ -599,11 +612,8 @@ namespace FlaxEngine.Interop
|
||||
#endif
|
||||
public static class ManagedToNative
|
||||
{
|
||||
public static unsafe IntPtr ConvertToUnmanaged(string managed)
|
||||
{
|
||||
return managed == null ? IntPtr.Zero : ManagedHandle.ToIntPtr(managed, GCHandleType.Weak);
|
||||
}
|
||||
|
||||
public static string ConvertToManaged(IntPtr unmanaged) => ManagedString.ToManaged(unmanaged);
|
||||
public static unsafe IntPtr ConvertToUnmanaged(string managed) => managed == null ? IntPtr.Zero : ManagedHandle.ToIntPtr(managed, GCHandleType.Weak);
|
||||
public static void Free(IntPtr unmanaged)
|
||||
{
|
||||
//ManagedString.Free(unmanaged); // No need to free weak handles
|
||||
|
||||
@@ -184,7 +184,7 @@ namespace FlaxEngine.Interop
|
||||
{
|
||||
string moduleName = Marshal.PtrToStringAnsi(moduleNamePtr);
|
||||
string modulePath = Marshal.PtrToStringAnsi(modulePathPtr);
|
||||
nativeLibraryPaths[moduleName] = modulePath;
|
||||
libraryPaths[moduleName] = modulePath;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
@@ -297,7 +297,7 @@ namespace FlaxEngine.Interop
|
||||
internal static void GetClassFields(ManagedHandle typeHandle, NativeFieldDefinitions** classFields, int* classFieldsCount)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
var fields = type.GetFields(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
|
||||
NativeFieldDefinitions* arr = (NativeFieldDefinitions*)NativeAlloc(fields.Length, Unsafe.SizeOf<NativeFieldDefinitions>());
|
||||
for (int i = 0; i < fields.Length; i++)
|
||||
@@ -331,7 +331,7 @@ namespace FlaxEngine.Interop
|
||||
internal static void GetClassProperties(ManagedHandle typeHandle, NativePropertyDefinitions** classProperties, int* classPropertiesCount)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
var properties = type.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
|
||||
var arr = (NativePropertyDefinitions*)NativeAlloc(properties.Length, Unsafe.SizeOf<NativePropertyDefinitions>());
|
||||
for (int i = 0; i < properties.Length; i++)
|
||||
@@ -804,8 +804,8 @@ namespace FlaxEngine.Interop
|
||||
[UnmanagedCallersOnly]
|
||||
internal static IntPtr FieldGetValueBoxed(ManagedHandle fieldOwnerHandle, ManagedHandle fieldHandle)
|
||||
{
|
||||
object fieldOwner = fieldOwnerHandle.Target;
|
||||
FieldHolder field = Unsafe.As<FieldHolder>(fieldHandle.Target);
|
||||
object fieldOwner = field.field.IsStatic ? null : fieldOwnerHandle.Target;
|
||||
object fieldValue = field.field.GetValue(fieldOwner);
|
||||
return Invoker.MarshalReturnValueGeneric(field.field.FieldType, fieldValue);
|
||||
}
|
||||
@@ -909,7 +909,7 @@ namespace FlaxEngine.Interop
|
||||
loadedNativeLibraries.Remove(nativeLibraryName);
|
||||
}
|
||||
if (nativeLibraryName != null)
|
||||
nativeLibraryPaths.Remove(nativeLibraryName);
|
||||
libraryPaths.Remove(nativeLibraryName);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace FlaxEngine.Interop
|
||||
private static Dictionary<Type, int> _typeSizeCache = new();
|
||||
|
||||
private static Dictionary<string, IntPtr> loadedNativeLibraries = new();
|
||||
internal static Dictionary<string, string> nativeLibraryPaths = new();
|
||||
internal static Dictionary<string, string> libraryPaths = new();
|
||||
private static Dictionary<Assembly, string> assemblyOwnedNativeLibraries = new();
|
||||
internal static AssemblyLoadContext scriptingAssemblyLoadContext;
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace FlaxEngine.Interop
|
||||
{
|
||||
if (!loadedNativeLibraries.TryGetValue(libraryName, out IntPtr nativeLibrary))
|
||||
{
|
||||
if (!nativeLibraryPaths.TryGetValue(libraryName, out var nativeLibraryPath))
|
||||
if (!libraryPaths.TryGetValue(libraryName, out var nativeLibraryPath))
|
||||
nativeLibraryPath = libraryName;
|
||||
|
||||
nativeLibrary = NativeLibrary.Load(nativeLibraryPath, assembly, dllImportSearchPath);
|
||||
@@ -101,9 +101,9 @@ namespace FlaxEngine.Interop
|
||||
private static Assembly OnScriptingAssemblyLoadContextResolving(AssemblyLoadContext assemblyLoadContext, AssemblyName assemblyName)
|
||||
{
|
||||
// FIXME: There should be a better way to resolve the path to EditorTargetPath where the dependencies are stored
|
||||
foreach (string nativeLibraryPath in nativeLibraryPaths.Values)
|
||||
foreach (string libraryPath in libraryPaths.Values)
|
||||
{
|
||||
string editorTargetPath = Path.GetDirectoryName(nativeLibraryPath);
|
||||
string editorTargetPath = Path.GetDirectoryName(libraryPath);
|
||||
|
||||
var assemblyPath = Path.Combine(editorTargetPath, assemblyName.Name + ".dll");
|
||||
if (File.Exists(assemblyPath))
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace
|
||||
FORCE_INLINE void InitFilter(dtQueryFilter& filter)
|
||||
{
|
||||
Platform::MemoryCopy(filter.m_areaCost, NavMeshRuntime::NavAreasCosts, sizeof(NavMeshRuntime::NavAreasCosts));
|
||||
static_assert(sizeof(dtQueryFilter::m_areaCost) == sizeof(NavMeshRuntime::NavAreasCosts), "Invalid navmesh area cost list.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -462,6 +462,9 @@ int32 MacPlatform::CreateProcess(CreateProcessSettings& settings)
|
||||
}
|
||||
}
|
||||
|
||||
// Sanatize the string if the exePath has spaces with properly espcaped spaces for popen
|
||||
exePath.Replace(TEXT(" "), TEXT("\\ "));
|
||||
|
||||
const String cmdLine = exePath + TEXT(" ") + settings.Arguments;
|
||||
const StringAsANSI<> cmdLineAnsi(*cmdLine, cmdLine.Length());
|
||||
FILE* pipe = popen(cmdLineAnsi.Get(), "r");
|
||||
|
||||
@@ -1010,12 +1010,36 @@ void ManagedBinaryModule::InitType(MClass* mclass)
|
||||
}
|
||||
if (baseType.Module == this)
|
||||
InitType(baseClass); // Ensure base is initialized before
|
||||
|
||||
baseType.Module->TypeNameToTypeIndex.TryGet(baseClass->GetFullName(), *(int32*)&baseType.TypeIndex);
|
||||
|
||||
// So we must special case this flow of a generic class of which its possible the generic base class is not in the same module
|
||||
if (baseType.TypeIndex == -1 && baseClass->IsGeneric())
|
||||
{
|
||||
auto genericNameIndex = baseClass->GetFullName().FindLast('`');
|
||||
// we add 2 because of the way generic names work its `N
|
||||
auto genericClassName = baseClass->GetFullName().Substring(0, genericNameIndex + 2);
|
||||
|
||||
// We check for the generic class name instead of the baseclass fullname
|
||||
baseType.Module->TypeNameToTypeIndex.TryGet(genericClassName, *(int32*)&baseType.TypeIndex);
|
||||
}
|
||||
|
||||
if (!baseType)
|
||||
{
|
||||
LOG(Error, "Missing base class for managed class {0} from assembly {1}.", String(typeName), Assembly->ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (baseType.TypeIndex == -1)
|
||||
{
|
||||
if (baseType.Module)
|
||||
LOG(Error, "Missing base class for managed class {0} from assembly {1}.", String(baseClass->GetFullName()), baseType.Module->GetName().ToString());
|
||||
else
|
||||
// Not sure this can happen but never hurts to account for it
|
||||
LOG(Error, "Missing base class for managed class {0} from unknown assembly.", String(baseClass->GetFullName()));
|
||||
return;
|
||||
}
|
||||
|
||||
ScriptingTypeHandle nativeType = baseType;
|
||||
while (true)
|
||||
{
|
||||
|
||||
@@ -719,6 +719,13 @@ bool MAssembly::LoadImage(const String& assemblyPath, const StringView& nativePa
|
||||
StringAnsi nativeName = _name.EndsWith(".CSharp") ? StringAnsi(_name.Get(), _name.Length() - 7) : StringAnsi(_name);
|
||||
RegisterNativeLibrary(nativeName.Get(), StringAnsi(nativePath).Get());
|
||||
}
|
||||
#if USE_EDITOR
|
||||
// Register the editor module location for Assembly resolver
|
||||
else
|
||||
{
|
||||
RegisterNativeLibrary(_name.Get(), StringAnsi(assemblyPath).Get());
|
||||
}
|
||||
#endif
|
||||
|
||||
_hasCachedClasses = false;
|
||||
_assemblyPath = assemblyPath;
|
||||
@@ -898,7 +905,6 @@ const Array<MMethod*>& MClass::GetMethods() const
|
||||
NativeMethodDefinitions& definition = methods[i];
|
||||
MMethod* method = New<MMethod>(const_cast<MClass*>(this), StringAnsi(definition.name), definition.handle, definition.numParameters, definition.methodAttributes);
|
||||
_methods.Add(method);
|
||||
|
||||
MCore::GC::FreeMemory((void*)definition.name);
|
||||
}
|
||||
MCore::GC::FreeMemory(methods);
|
||||
@@ -932,7 +938,6 @@ const Array<MField*>& MClass::GetFields() const
|
||||
NativeFieldDefinitions& definition = fields[i];
|
||||
MField* field = New<MField>(const_cast<MClass*>(this), definition.fieldHandle, definition.name, definition.fieldType, definition.fieldAttributes);
|
||||
_fields.Add(field);
|
||||
|
||||
MCore::GC::FreeMemory((void*)definition.name);
|
||||
}
|
||||
MCore::GC::FreeMemory(fields);
|
||||
@@ -977,7 +982,6 @@ const Array<MProperty*>& MClass::GetProperties() const
|
||||
const NativePropertyDefinitions& definition = foundProperties[i];
|
||||
MProperty* property = New<MProperty>(const_cast<MClass*>(this), definition.name, definition.getterHandle, definition.setterHandle, definition.getterAttributes, definition.setterAttributes);
|
||||
_properties.Add(property);
|
||||
|
||||
MCore::GC::FreeMemory((void*)definition.name);
|
||||
}
|
||||
MCore::GC::FreeMemory(foundProperties);
|
||||
@@ -1541,7 +1545,16 @@ bool InitHostfxr()
|
||||
get_hostfxr_params.size = sizeof(hostfxr_initialize_parameters);
|
||||
get_hostfxr_params.assembly_path = libraryPath.Get();
|
||||
#if PLATFORM_MAC
|
||||
get_hostfxr_params.dotnet_root = "/usr/local/share/dotnet";
|
||||
::String macOSDotnetRoot = TEXT("/usr/local/share/dotnet");
|
||||
#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(_M_X64)
|
||||
// When emulating x64 on arm
|
||||
const ::String dotnetRootEmulated = macOSDotnetRoot / TEXT("x64");
|
||||
if (FileSystem::FileExists(dotnetRootEmulated / TEXT("dotnet"))) {
|
||||
macOSDotnetRoot = dotnetRootEmulated;
|
||||
}
|
||||
#endif
|
||||
const FLAX_CORECLR_STRING& finalDotnetRootPath = FLAX_CORECLR_STRING(macOSDotnetRoot);
|
||||
get_hostfxr_params.dotnet_root = finalDotnetRootPath.Get();
|
||||
#else
|
||||
get_hostfxr_params.dotnet_root = nullptr;
|
||||
#endif
|
||||
@@ -1588,7 +1601,10 @@ bool InitHostfxr()
|
||||
void* hostfxr = Platform::LoadLibrary(path.Get());
|
||||
if (hostfxr == nullptr)
|
||||
{
|
||||
LOG(Fatal, "Failed to load hostfxr library ({0})", path);
|
||||
if (FileSystem::FileExists(path))
|
||||
LOG(Fatal, "Failed to load hostfxr library, possible platform/architecture mismatch with the library. See log for more information. ({0})", path);
|
||||
else
|
||||
LOG(Fatal, "Failed to load hostfxr library ({0})", path);
|
||||
return true;
|
||||
}
|
||||
hostfxr_initialize_for_runtime_config = (hostfxr_initialize_for_runtime_config_fn)Platform::GetProcAddress(hostfxr, "hostfxr_initialize_for_runtime_config");
|
||||
@@ -1627,7 +1643,28 @@ bool InitHostfxr()
|
||||
if (rc != 0 || handle == nullptr)
|
||||
{
|
||||
hostfxr_close(handle);
|
||||
LOG(Fatal, "Failed to initialize hostfxr: {0:x} ({1})", (unsigned int)rc, String(init_params.dotnet_root));
|
||||
if (rc == 0x80008096) // FrameworkMissingFailure
|
||||
{
|
||||
String platformStr;
|
||||
switch (PLATFORM_TYPE)
|
||||
{
|
||||
case PlatformType::Windows:
|
||||
case PlatformType::UWP:
|
||||
platformStr = PLATFORM_64BITS ? "Windows x64" : "Windows x86";
|
||||
break;
|
||||
case PlatformType::Linux:
|
||||
platformStr = PLATFORM_ARCH_ARM64 ? "Linux Arm64" : PLATFORM_ARCH_ARM ? "Linux Arm32" : PLATFORM_64BITS ? "Linux x64" : "Linux x86";
|
||||
break;
|
||||
case PlatformType::Mac:
|
||||
platformStr = PLATFORM_ARCH_ARM || PLATFORM_ARCH_ARM64 ? "macOS Arm64" : PLATFORM_64BITS ? "macOS x64" : "macOS x86";
|
||||
break;
|
||||
default:;
|
||||
platformStr = "";
|
||||
}
|
||||
LOG(Fatal, "Failed to resolve compatible .NET runtime version in '{0}'. Make sure the correct platform version for runtime is installed ({1})", platformStr, String(init_params.dotnet_root));
|
||||
}
|
||||
else
|
||||
LOG(Fatal, "Failed to initialize hostfxr: {0:x} ({1})", (unsigned int)rc, String(init_params.dotnet_root));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace FlaxEngine.Tests
|
||||
{
|
||||
var result = 0;
|
||||
var libraryName = "FlaxEngine";
|
||||
var library = NativeLibrary.Load(Interop.NativeInterop.nativeLibraryPaths[libraryName]);
|
||||
var library = NativeLibrary.Load(Interop.NativeInterop.libraryPaths[libraryName]);
|
||||
if (library == IntPtr.Zero)
|
||||
return -1;
|
||||
var types = typeof(FlaxEngine.Object).Assembly.GetTypes();
|
||||
|
||||
@@ -43,7 +43,16 @@ public:
|
||||
void write(const char* message) override
|
||||
{
|
||||
String s(message);
|
||||
s.Replace('\n', ' ');
|
||||
if (s.Length() <= 0)
|
||||
return;
|
||||
for (int32 i = 0; i < s.Length(); i++)
|
||||
{
|
||||
Char& c = s[i];
|
||||
if (c == '\n')
|
||||
c = ' ';
|
||||
else if (c >= 255)
|
||||
c = '?';
|
||||
}
|
||||
LOG(Info, "[Assimp]: {0}", s);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -60,6 +60,7 @@ public class Slider : ContainerControl
|
||||
private float _thumbCenter;
|
||||
private Float2 _thumbSize = new Float2(16, 16);
|
||||
private bool _isSliding;
|
||||
private bool _mouseOverThumb;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value (normalized to range 0-100).
|
||||
@@ -163,21 +164,27 @@ public class Slider : ContainerControl
|
||||
public IBrush FillTrackBrush { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The color of the slider thumb when it's not selected
|
||||
/// The color of the slider thumb when it's not selected.
|
||||
/// </summary>
|
||||
[EditorDisplay("Thumb Style"), EditorOrder(2030), Tooltip("The color of the slider thumb when it's not selected."), ExpandGroups]
|
||||
public Color ThumbColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The color of the slider thumb when it's highlighted.
|
||||
/// </summary>
|
||||
[EditorDisplay("Thumb Style"), EditorOrder(2031), Tooltip("The color of the slider thumb when it's highlighted.")]
|
||||
public Color ThumbColorHighlighted { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The color of the slider thumb when it's selected
|
||||
/// The color of the slider thumb when it's selected.
|
||||
/// </summary>
|
||||
[EditorDisplay("Thumb Style"), EditorOrder(2031), Tooltip("The color of the slider thumb when it's selected.")]
|
||||
[EditorDisplay("Thumb Style"), EditorOrder(2032), Tooltip("The color of the slider thumb when it's selected.")]
|
||||
public Color ThumbColorSelected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the brush used for slider thumb drawing.
|
||||
/// </summary>
|
||||
[EditorDisplay("Thumb Style"), EditorOrder(2032), Tooltip("The brush of the slider thumb.")]
|
||||
[EditorDisplay("Thumb Style"), EditorOrder(2033), Tooltip("The brush of the slider thumb.")]
|
||||
public IBrush ThumbBrush { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -222,6 +229,7 @@ public class Slider : ContainerControl
|
||||
TrackFillLineColor = style.LightBackground;
|
||||
ThumbColor = style.BackgroundNormal;
|
||||
ThumbColorSelected = style.BackgroundSelected;
|
||||
ThumbColorHighlighted = style.BackgroundHighlighted;
|
||||
UpdateThumb();
|
||||
}
|
||||
|
||||
@@ -270,7 +278,7 @@ public class Slider : ContainerControl
|
||||
}
|
||||
|
||||
// Draw thumb
|
||||
var thumbColor = _isSliding ? ThumbColorSelected : ThumbColor;
|
||||
var thumbColor = _isSliding ? ThumbColorSelected : (_mouseOverThumb ? ThumbColorHighlighted : ThumbColor);
|
||||
if (ThumbBrush != null)
|
||||
ThumbBrush.Draw(_thumbRect, thumbColor);
|
||||
else
|
||||
@@ -317,6 +325,7 @@ public class Slider : ContainerControl
|
||||
/// <inheritdoc />
|
||||
public override void OnMouseMove(Float2 location)
|
||||
{
|
||||
_mouseOverThumb = _thumbRect.Contains(location);
|
||||
if (_isSliding)
|
||||
{
|
||||
// Update sliding
|
||||
|
||||
Reference in New Issue
Block a user