diff --git a/Source/Editor/CustomEditors/Editors/AssetRefEditor.cs b/Source/Editor/CustomEditors/Editors/AssetRefEditor.cs
index e89c80372..cfba940c2 100644
--- a/Source/Editor/CustomEditors/Editors/AssetRefEditor.cs
+++ b/Source/Editor/CustomEditors/Editors/AssetRefEditor.cs
@@ -80,6 +80,8 @@ namespace FlaxEditor.CustomEditors.Editors
assetType = customType;
else if (!Content.Settings.GameSettings.OptionalPlatformSettings.Contains(assetReference.TypeName))
Debug.LogWarning(string.Format("Unknown asset type '{0}' to use for asset picker filter.", assetReference.TypeName));
+ else
+ assetType = ScriptType.Void;
}
}
diff --git a/Source/Editor/GUI/AssetPicker.cs b/Source/Editor/GUI/AssetPicker.cs
index bfded5380..3e5d22eb0 100644
--- a/Source/Editor/GUI/AssetPicker.cs
+++ b/Source/Editor/GUI/AssetPicker.cs
@@ -475,22 +475,31 @@ namespace FlaxEditor.GUI
if (_type != ScriptType.Null)
{
// Show asset picker popup
- AssetSearchPopup.Show(this, Button1Rect.BottomLeft, IsValid, item =>
+ var popup = AssetSearchPopup.Show(this, Button1Rect.BottomLeft, IsValid, item =>
{
SelectedItem = item;
RootWindow.Focus();
Focus();
});
+ if (_selected != null)
+ {
+ var selectedAssetName = Path.GetFileNameWithoutExtension(_selected.Path);
+ popup.ScrollToAndHighlightItemByName(selectedAssetName);
+ }
}
else
{
// Show content item picker popup
- ContentSearchPopup.Show(this, Button1Rect.BottomLeft, IsValid, item =>
+ var popup = ContentSearchPopup.Show(this, Button1Rect.BottomLeft, IsValid, item =>
{
SelectedItem = item;
RootWindow.Focus();
Focus();
});
+ if (_selectedItem != null)
+ {
+ popup.ScrollToAndHighlightItemByName(_selectedItem.ShortName);
+ }
}
}
else if (_selected != null || _selectedItem != null)
diff --git a/Source/Editor/GUI/ItemsListContextMenu.cs b/Source/Editor/GUI/ItemsListContextMenu.cs
index ae470235d..42d236991 100644
--- a/Source/Editor/GUI/ItemsListContextMenu.cs
+++ b/Source/Editor/GUI/ItemsListContextMenu.cs
@@ -265,6 +265,35 @@ namespace FlaxEditor.GUI
_searchBox.Focus();
}
+ ///
+ /// Scrolls the scroll panel to a specific Item
+ ///
+ /// The item to scroll to.
+ public void ScrollViewTo(Item item)
+ {
+ _scrollPanel.ScrollViewTo(item, true);
+ }
+
+ ///
+ /// Scrolls to the item and focuses it by name.
+ ///
+ /// The item name.
+ public void ScrollToAndHighlightItemByName(string itemName)
+ {
+ foreach (var child in ItemsPanel.Children)
+ {
+ if (child is not ItemsListContextMenu.Item item)
+ continue;
+ if (string.Equals(item.Name, itemName, StringComparison.Ordinal))
+ {
+ // Highlight and scroll to item
+ item.Focus();
+ ScrollViewTo(item);
+ break;
+ }
+ }
+ }
+
///
/// Sorts the items list (by item name by default).
///
diff --git a/Source/Engine/Animations/AnimationGraph.cs b/Source/Engine/Animations/AnimationGraph.cs
index 46b3acfc1..2e26b8370 100644
--- a/Source/Engine/Animations/AnimationGraph.cs
+++ b/Source/Engine/Animations/AnimationGraph.cs
@@ -1,7 +1,6 @@
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
using System;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
@@ -94,9 +93,11 @@ namespace FlaxEngine
public AnimatedModel Instance;
}
+ [HideInEditor]
[CustomMarshaller(typeof(Context), MarshalMode.Default, typeof(ContextMarshaller))]
internal static class ContextMarshaller
{
+ [HideInEditor]
[StructLayout(LayoutKind.Sequential)]
public struct ContextNative
{
@@ -116,7 +117,7 @@ namespace FlaxEngine
internal static Context ToManaged(ContextNative managed)
{
- return new Context()
+ return new Context
{
Graph = managed.Graph,
GraphExecutor = managed.GraphExecutor,
@@ -129,9 +130,10 @@ namespace FlaxEngine
Instance = AnimatedModelMarshaller.ConvertToManaged(managed.Instance),
};
}
+
internal static ContextNative ToNative(Context managed)
{
- return new ContextNative()
+ return new ContextNative
{
Graph = managed.Graph,
GraphExecutor = managed.GraphExecutor,
@@ -144,6 +146,7 @@ namespace FlaxEngine
Instance = AnimatedModelMarshaller.ConvertToUnmanaged(managed.Instance),
};
}
+
internal static void Free(ContextNative unmanaged)
{
}
@@ -243,6 +246,12 @@ namespace FlaxEngine
throw new ArgumentNullException(nameof(source));
if (destination == null)
throw new ArgumentNullException(nameof(destination));
+ if (source->NodesCount <= 0 || source->NodesCount > 4096)
+ throw new ArgumentOutOfRangeException(nameof(source));
+ if (destination->NodesCount <= 0 || destination->NodesCount > 4096)
+ throw new ArgumentOutOfRangeException(nameof(destination));
+ if (source->NodesCount != destination->NodesCount)
+ throw new ArgumentOutOfRangeException();
destination->NodesCount = source->NodesCount;
destination->Unused = source->Unused;
Utils.MemoryCopy(new IntPtr(destination->Nodes), new IntPtr(source->Nodes), (ulong)(source->NodesCount * sizeof(Transform)));
diff --git a/Source/Engine/Animations/Graph/AnimGraph.Custom.cpp b/Source/Engine/Animations/Graph/AnimGraph.Custom.cpp
index d74c523f1..cdd5b03eb 100644
--- a/Source/Engine/Animations/Graph/AnimGraph.Custom.cpp
+++ b/Source/Engine/Animations/Graph/AnimGraph.Custom.cpp
@@ -5,7 +5,6 @@
#include "Engine/Scripting/Scripting.h"
#include "Engine/Scripting/BinaryModule.h"
#include "Engine/Scripting/ManagedCLR/MCore.h"
-#include "Engine/Scripting/ManagedCLR/MDomain.h"
#include "Engine/Scripting/ManagedCLR/MMethod.h"
#include "Engine/Scripting/ManagedCLR/MClass.h"
#include "Engine/Scripting/ManagedCLR/MUtils.h"
@@ -189,12 +188,8 @@ bool AnimGraph::InitCustomNode(Node* node)
return false;
}
- // Create node values managed array
+ // Initialization can happen on Content Thread so ensure to have runtime attached
MCore::Thread::Attach();
- MArray* values = MCore::Array::New( MCore::TypeCache::Object, node->Values.Count());
- MObject** valuesPtr = MCore::Array::GetAddress(values);
- for (int32 i = 0; i < node->Values.Count(); i++)
- valuesPtr[i] = MUtils::BoxVariant(node->Values[i]);
// Allocate managed node object (create GC handle to prevent destruction)
MObject* obj = type->CreateInstance();
@@ -202,7 +197,7 @@ bool AnimGraph::InitCustomNode(Node* node)
// Initialize node
InternalInitData initData;
- initData.Values = values;
+ initData.Values = MUtils::ToArray(node->Values, MCore::TypeCache::Object);
initData.BaseModel = BaseModel.GetManagedInstance();
void* params[1];
params[0] = &initData;
@@ -211,7 +206,6 @@ bool AnimGraph::InitCustomNode(Node* node)
if (exception)
{
MCore::GCHandle::Free(handleGC);
-
MException ex(exception);
ex.Log(LogType::Warning, TEXT("AnimGraph"));
return false;
diff --git a/Source/Engine/Animations/Graph/AnimGroup.Animation.cpp b/Source/Engine/Animations/Graph/AnimGroup.Animation.cpp
index 31b97fb52..82842376e 100644
--- a/Source/Engine/Animations/Graph/AnimGroup.Animation.cpp
+++ b/Source/Engine/Animations/Graph/AnimGroup.Animation.cpp
@@ -235,8 +235,9 @@ void AnimGraphExecutor::ProcessAnimation(AnimGraphImpulse* nodes, AnimGraphNode*
const float nestedAnimLength = nestedAnim.Anim->GetLength();
const float nestedAnimDuration = nestedAnim.Anim->GetDuration();
const float nestedAnimSpeed = nestedAnim.Speed * speed;
- nestedAnimPos = nestedAnimPos / nestedAnimDuration * nestedAnimSpeed;
- nestedAnimPrevPos = nestedAnimPrevPos / nestedAnimDuration * nestedAnimSpeed;
+ const float frameRateMatchScale = (float)nestedAnim.Anim->Data.FramesPerSecond / (float)anim->Data.FramesPerSecond;
+ nestedAnimPos = nestedAnimPos / nestedAnimDuration * nestedAnimSpeed * frameRateMatchScale;
+ nestedAnimPrevPos = nestedAnimPrevPos / nestedAnimDuration * nestedAnimSpeed * frameRateMatchScale;
GetAnimSamplePos(nestedAnim.Loop, nestedAnimLength, nestedAnim.StartTime, nestedAnimPrevPos, nestedAnimPos, nestedAnimPos, nestedAnimPrevPos);
ProcessAnimation(nodes, node, true, nestedAnimLength, nestedAnimPos, nestedAnimPrevPos, nestedAnim.Anim, 1.0f, weight, mode);
diff --git a/Source/Engine/Content/Storage/FlaxStorage.cpp b/Source/Engine/Content/Storage/FlaxStorage.cpp
index 52d7c34b5..d530e5456 100644
--- a/Source/Engine/Content/Storage/FlaxStorage.cpp
+++ b/Source/Engine/Content/Storage/FlaxStorage.cpp
@@ -205,9 +205,6 @@ FlaxStorage::~FlaxStorage()
{
// Validate if has been disposed
ASSERT(IsDisposed());
-
- // Validate other fields
- // Note: disposed storage has no open files
CHECK(_chunksLock == 0);
CHECK(_refCount == 0);
ASSERT(_chunks.IsEmpty());
@@ -216,7 +213,6 @@ FlaxStorage::~FlaxStorage()
// Ensure to close any outstanding file handles to prevent file locking in case it failed to load
_file.DeleteAll();
#endif
-
}
FlaxStorage::LockData FlaxStorage::LockSafe()
@@ -550,11 +546,9 @@ bool FlaxStorage::Load()
}
break;
default:
- {
LOG(Warning, "Unsupported storage format version: {1}. {0}", ToString(), _version);
return true;
}
- }
// Mark as loaded (version number describes 'isLoaded' state)
_version = version;
@@ -573,7 +567,7 @@ bool FlaxStorage::Reload()
// Perform clean reloading
Dispose();
- bool failed = Load();
+ const bool failed = Load();
OnReloaded(this, failed);
@@ -1434,10 +1428,8 @@ void FlaxFile::GetEntries(Array& output) const
void FlaxFile::Dispose()
{
- // Base
FlaxStorage::Dispose();
- // Clean
_asset.ID = Guid::Empty;
}
@@ -1482,7 +1474,7 @@ bool FlaxPackage::HasAsset(const Guid& id) const
bool FlaxPackage::HasAsset(const AssetInfo& info) const
{
ASSERT(_path == info.Path);
- Entry* e = _entries.TryGet(info.ID);
+ const Entry* e = _entries.TryGet(info.ID);
return e && e->TypeName == info.TypeName;
}
@@ -1511,10 +1503,8 @@ void FlaxPackage::GetEntries(Array& output) const
void FlaxPackage::Dispose()
{
- // Base
FlaxStorage::Dispose();
- // Clean
_entries.Clear();
}
diff --git a/Source/Engine/Core/Types/Version.h b/Source/Engine/Core/Types/Version.h
index 57c6e10fe..1dc36ea38 100644
--- a/Source/Engine/Core/Types/Version.h
+++ b/Source/Engine/Core/Types/Version.h
@@ -72,15 +72,6 @@ public:
return _major;
}
- ///
- /// Gets the high 16 bits of the revision number.
- ///
- /// A 16-bit signed integer.
- FORCE_INLINE int16 MajorRevision() const
- {
- return static_cast(_revision >> 16);
- }
-
///
/// Gets the value of the minor component of the version number for the current Version object.
///
@@ -90,15 +81,6 @@ public:
return _minor;
}
- ///
- /// Gets the low 16 bits of the revision number.
- ///
- /// A 16-bit signed integer.
- FORCE_INLINE int16 MinorRevision() const
- {
- return static_cast(_revision & 65535);
- }
-
///
/// Gets the value of the revision component of the version number for the current Version object.
///
@@ -126,61 +108,26 @@ public:
return _major == obj._major && _minor == obj._minor && _build == obj._build && _revision == obj._revision;
}
- ///
- /// Determines whether two specified Version objects are equal.
- ///
- /// The other Version object.
- /// True if equals ; otherwise, false.
FORCE_INLINE bool operator==(const Version& other) const
{
return Equals(other);
}
-
- ///
- /// Determines whether the first specified Version object is greater than the second specified Version object.
- ///
- /// The first Version object.
- /// True if is greater than ; otherwise, false.
- FORCE_INLINE bool operator >(const Version& other) const
+ FORCE_INLINE bool operator>(const Version& other) const
{
return other < *this;
}
-
- ///
- /// Determines whether the first specified Version object is greater than or equal to the second specified Version object.
- /// /summary>
- /// The other Version object.
- /// True if is greater than or equal to ; otherwise, false.
- FORCE_INLINE bool operator >=(const Version& other) const
+ FORCE_INLINE bool operator>=(const Version& other) const
{
return other <= *this;
}
-
- ///
- /// Determines whether two specified Version objects are not equal.
- ///
- /// The other Version object.
- /// True if does not equal ; otherwise, false.
FORCE_INLINE bool operator!=(const Version& other) const
{
return !(*this == other);
}
-
- ///
- /// Determines whether the first specified Version object is less than the second specified Version object.
- ///
- /// The first other object.
- /// True if is less than ; otherwise, false.
FORCE_INLINE bool operator<(const Version& other) const
{
return CompareTo(other) < 0;
}
-
- ///
- /// Determines whether the first specified Version object is less than or equal to the second Version object.
- ///
- /// The other Version object.
- /// True if is less than or equal to ; otherwise, false.
FORCE_INLINE bool operator<=(const Version& other) const
{
return CompareTo(other) <= 0;
diff --git a/Source/Engine/Engine/NativeInterop.Managed.cs b/Source/Engine/Engine/NativeInterop.Managed.cs
index 797b02d5b..95146a95c 100644
--- a/Source/Engine/Engine/NativeInterop.Managed.cs
+++ b/Source/Engine/Engine/NativeInterop.Managed.cs
@@ -274,12 +274,12 @@ namespace FlaxEngine.Interop
#if FLAX_EDITOR
[HideInEditor]
#endif
- internal static class ManagedString
+ public static class ManagedString
{
internal static ManagedHandle EmptyStringHandle = ManagedHandle.Alloc(string.Empty);
[System.Diagnostics.DebuggerStepThrough]
- internal static unsafe IntPtr ToNative(string str)
+ public static unsafe IntPtr ToNative(string str)
{
if (str == null)
return IntPtr.Zero;
@@ -290,7 +290,7 @@ namespace FlaxEngine.Interop
}
[System.Diagnostics.DebuggerStepThrough]
- internal static unsafe IntPtr ToNativeWeak(string str)
+ public static unsafe IntPtr ToNativeWeak(string str)
{
if (str == null)
return IntPtr.Zero;
@@ -301,7 +301,7 @@ namespace FlaxEngine.Interop
}
[System.Diagnostics.DebuggerStepThrough]
- internal static string ToManaged(IntPtr ptr)
+ public static string ToManaged(IntPtr ptr)
{
if (ptr == IntPtr.Zero)
return null;
@@ -309,7 +309,7 @@ namespace FlaxEngine.Interop
}
[System.Diagnostics.DebuggerStepThrough]
- internal static void Free(IntPtr ptr)
+ public static void Free(IntPtr ptr)
{
if (ptr == IntPtr.Zero)
return;
diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs
index acfd7181b..da372ac90 100644
--- a/Source/Engine/Engine/NativeInterop.cs
+++ b/Source/Engine/Engine/NativeInterop.cs
@@ -444,7 +444,7 @@ namespace FlaxEngine.Interop
}
else
{
- toManagedFieldMethod = typeof(MarshalHelper<>.ReferenceTypeField<>).MakeGenericType(type, fieldType).GetMethod(nameof(MarshalHelper.ReferenceTypeField.ToManagedField), bindingFlags);
+ toManagedFieldMethod = typeof(MarshalHelper<>.ReferenceTypeField<>).MakeGenericType(type, arrayElementType).GetMethod(nameof(MarshalHelper.ReferenceTypeField.ToManagedFieldArray), bindingFlags);
toNativeFieldMethod = typeof(MarshalHelper<>.ReferenceTypeField<>).MakeGenericType(type, fieldType).GetMethod(nameof(MarshalHelper.ReferenceTypeField.ToNativeField), bindingFlags);
}
}
@@ -663,6 +663,17 @@ namespace FlaxEngine.Interop
MarshalHelperReferenceType.ToManaged(ref fieldValueRef, Unsafe.Read(fieldPtr.ToPointer()), false);
}
+ internal static void ToManagedFieldArray(FieldInfo field, ref T fieldOwner, IntPtr fieldPtr, out int fieldOffset)
+ {
+ fieldOffset = Unsafe.SizeOf();
+ IntPtr fieldStartPtr = fieldPtr;
+ fieldPtr = EnsureAlignment(fieldPtr, IntPtr.Size);
+ fieldOffset += (fieldPtr - fieldStartPtr).ToInt32();
+
+ ref TField[] fieldValueRef = ref GetFieldReference(field, ref fieldOwner);
+ MarshalHelperReferenceType.ToManagedArray(ref fieldValueRef, Unsafe.Read(fieldPtr.ToPointer()), false);
+ }
+
internal static void ToNativeField(FieldInfo field, ref T fieldOwner, IntPtr fieldPtr, out int fieldOffset)
{
fieldOffset = Unsafe.SizeOf();
@@ -691,14 +702,15 @@ namespace FlaxEngine.Interop
internal static void ToManaged(ref T managedValue, IntPtr nativePtr, bool byRef)
{
Type type = typeof(T);
- if (type.IsByRef || byRef)
+ byRef |= type.IsByRef;
+ if (byRef)
{
if (type.IsByRef)
type = type.GetElementType();
Assert.IsTrue(type.IsValueType);
}
- if (type == typeof(IntPtr))
+ if (type == typeof(IntPtr) && byRef)
managedValue = (T)(object)nativePtr;
else if (type == typeof(ManagedHandle))
managedValue = (T)(object)ManagedHandle.FromIntPtr(nativePtr);
@@ -778,10 +790,12 @@ namespace FlaxEngine.Interop
if (type == typeof(string))
managedValue = Unsafe.As(ManagedString.ToManaged(nativePtr));
+ else if (nativePtr == IntPtr.Zero)
+ managedValue = null;
else if (type.IsClass)
- managedValue = nativePtr != IntPtr.Zero ? Unsafe.As(ManagedHandle.FromIntPtr(nativePtr).Target) : null;
+ managedValue = Unsafe.As(ManagedHandle.FromIntPtr(nativePtr).Target);
else if (type.IsInterface) // Dictionary
- managedValue = nativePtr != IntPtr.Zero ? Unsafe.As(ManagedHandle.FromIntPtr(nativePtr).Target) : null;
+ managedValue = Unsafe.As(ManagedHandle.FromIntPtr(nativePtr).Target);
else
throw new NotImplementedException();
}
diff --git a/Source/Engine/Scripting/Internal/ManagedSerialization.cpp b/Source/Engine/Scripting/Internal/ManagedSerialization.cpp
index f1543a326..f5ea46b5e 100644
--- a/Source/Engine/Scripting/Internal/ManagedSerialization.cpp
+++ b/Source/Engine/Scripting/Internal/ManagedSerialization.cpp
@@ -108,7 +108,7 @@ void ManagedSerialization::Deserialize(const StringAnsiView& data, MObject* obje
// Prepare arguments
void* args[3];
args[0] = object;
- args[1] = (void*)str;
+ args[1] = (void*)&str;
args[2] = (void*)&len;
// Call serialization tool
diff --git a/Source/Engine/Scripting/ManagedCLR/MUtils.cpp b/Source/Engine/Scripting/ManagedCLR/MUtils.cpp
index d97ff92cd..be8e10fab 100644
--- a/Source/Engine/Scripting/ManagedCLR/MUtils.cpp
+++ b/Source/Engine/Scripting/ManagedCLR/MUtils.cpp
@@ -3,7 +3,6 @@
#include "MUtils.h"
#include "MClass.h"
#include "MCore.h"
-#include "MDomain.h"
#include "Engine/Core/Log.h"
#include "Engine/Core/Types/DataContainer.h"
#include "Engine/Core/Types/Version.h"
@@ -449,7 +448,7 @@ Variant MUtils::UnboxVariant(MObject* value)
{
auto& a = array[i];
a.SetType(elementType);
- Platform::MemoryCopy(&a.AsData,(byte*)ptr + elementSize * i, elementSize);
+ Platform::MemoryCopy(&a.AsData, (byte*)ptr + elementSize * i, elementSize);
}
break;
case VariantType::Transform:
@@ -1004,11 +1003,11 @@ MClass* MUtils::GetClass(const Variant& value)
case VariantType::Enum:
return Scripting::FindClass(StringAnsiView(value.Type.TypeName));
case VariantType::ManagedObject:
- {
- MObject* obj = (MObject*)value;
- if (obj)
- return MCore::Object::GetClass(obj);
- }
+ {
+ MObject* obj = (MObject*)value;
+ if (obj)
+ return MCore::Object::GetClass(obj);
+ }
default: ;
}
return GetClass(value.Type);
@@ -1224,10 +1223,10 @@ MObject* MUtils::ToManaged(const Version& value)
auto versionToManaged = scriptingClass->GetMethod("VersionToManaged", 4);
CHECK_RETURN(versionToManaged, nullptr);
- int major = value.Major();
- int minor = value.Minor();
- int build = value.Build();
- int revision = value.Revision();
+ int32 major = value.Major();
+ int32 minor = value.Minor();
+ int32 build = value.Build();
+ int32 revision = value.Revision();
void* params[4];
params[0] = &major;
@@ -1244,26 +1243,29 @@ MObject* MUtils::ToManaged(const Version& value)
Version MUtils::ToNative(MObject* value)
{
+ Version result;
if (value)
#if USE_NETCORE
{
- auto ver = Version();
-
auto scriptingClass = Scripting::GetStaticClass();
- CHECK_RETURN(scriptingClass, ver);
- auto versionToNative = scriptingClass->GetMethod("VersionToNative", 2);
- CHECK_RETURN(versionToNative, ver);
+ CHECK_RETURN(scriptingClass, result);
+ auto versionToNative = scriptingClass->GetMethod("VersionToNative", 5);
+ CHECK_RETURN(versionToNative, result);
- void* params[2];
+ void* params[5];
params[0] = value;
- params[1] = &ver;
+ params[1] = (byte*)&result;
+ params[2] = (byte*)&result + sizeof(int32);
+ params[3] = (byte*)&result + sizeof(int32) * 2;
+ params[4] = (byte*)&result + sizeof(int32) * 3;
versionToNative->Invoke(nullptr, params, nullptr);
- return ver;
+
+ return result;
}
#else
return *(Version*)MCore::Object::Unbox(value);
#endif
- return Version();
+ return result;
}
#endif
diff --git a/Source/Engine/Scripting/Scripting.cs b/Source/Engine/Scripting/Scripting.cs
index 7a91b2d96..2b49d97d4 100644
--- a/Source/Engine/Scripting/Scripting.cs
+++ b/Source/Engine/Scripting/Scripting.cs
@@ -229,22 +229,24 @@ namespace FlaxEngine
return ManagedHandle.Alloc(new CultureInfo(lcid));
}
- internal static void VersionToNative(ManagedHandle versionHandle, IntPtr nativePtr)
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct VersionNative
+ {
+ public int Major;
+ public int Minor;
+ public int Build;
+ public int Revision;
+ }
+
+ internal static void VersionToNative(ManagedHandle versionHandle, ref int major, ref int minor, ref int build, ref int revision)
{
Version version = Unsafe.As(versionHandle.Target);
if (version != null)
{
- Marshal.WriteInt32(nativePtr, 0, version.Major);
- Marshal.WriteInt32(nativePtr, 4, version.Minor);
- Marshal.WriteInt32(nativePtr, 8, version.Build);
- Marshal.WriteInt32(nativePtr, 12, version.Revision);
- }
- else
- {
- Marshal.WriteInt32(nativePtr, 0, 0);
- Marshal.WriteInt32(nativePtr, 4, 0);
- Marshal.WriteInt32(nativePtr, 8, -1);
- Marshal.WriteInt32(nativePtr, 12, -1);
+ major = version.Major;
+ minor = version.Minor;
+ build = version.Build;
+ revision = version.Revision;
}
}
diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs
index 920e74f67..087dc898f 100644
--- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs
+++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs
@@ -1203,6 +1203,8 @@ namespace Flax.Build.Bindings
contents.Append("ref ");
else if (parameterInfo.IsThis)
contents.Append("this ");
+ else if (parameterInfo.IsParams)
+ contents.Append("params ");
contents.Append(managedType);
contents.Append(' ');
contents.Append(parameterInfo.Name);
@@ -1263,6 +1265,8 @@ namespace Flax.Build.Bindings
contents.Append("ref ");
else if (parameterInfo.IsThis)
contents.Append("this ");
+ else if (parameterInfo.IsParams)
+ contents.Append("params ");
contents.Append(managedType);
contents.Append(' ');
contents.Append(parameterInfo.Name);
@@ -1988,6 +1992,8 @@ namespace Flax.Build.Bindings
contents.Append("ref ");
else if (parameterInfo.IsThis)
contents.Append("this ");
+ else if (parameterInfo.IsParams)
+ contents.Append("params ");
contents.Append(managedType);
contents.Append(' ');
contents.Append(parameterInfo.Name);
diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs
index 72896f186..c2a785c9c 100644
--- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs
+++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs
@@ -19,7 +19,7 @@ namespace Flax.Build.Bindings
partial class BindingsGenerator
{
private static readonly Dictionary TypeCache = new Dictionary();
- private const int CacheVersion = 18;
+ private const int CacheVersion = 19;
internal static void Write(BinaryWriter writer, string e)
{
diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs
index 1eeefaf27..d4fcd9629 100644
--- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs
+++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs
@@ -337,6 +337,9 @@ namespace Flax.Build.Bindings
case "this":
currentParam.IsThis = true;
break;
+ case "params":
+ currentParam.IsParams = true;
+ break;
case "attributes":
currentParam.Attributes = tag.Value;
break;
diff --git a/Source/Tools/Flax.Build/Bindings/FunctionInfo.cs b/Source/Tools/Flax.Build/Bindings/FunctionInfo.cs
index 3676e8e76..bae49e98e 100644
--- a/Source/Tools/Flax.Build/Bindings/FunctionInfo.cs
+++ b/Source/Tools/Flax.Build/Bindings/FunctionInfo.cs
@@ -19,6 +19,7 @@ namespace Flax.Build.Bindings
public bool IsRef;
public bool IsOut;
public bool IsThis;
+ public bool IsParams;
public bool HasDefaultValue => !string.IsNullOrEmpty(DefaultValue);
@@ -37,6 +38,7 @@ namespace Flax.Build.Bindings
writer.Write(IsRef);
writer.Write(IsOut);
writer.Write(IsThis);
+ writer.Write(IsParams);
}
public void Read(BinaryReader reader)
@@ -49,6 +51,7 @@ namespace Flax.Build.Bindings
IsRef = reader.ReadBoolean();
IsOut = reader.ReadBoolean();
IsThis = reader.ReadBoolean();
+ IsParams = reader.ReadBoolean();
}
public override string ToString()