Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -25,6 +25,16 @@ namespace FlaxEditor.Content
|
||||
/// </summary>
|
||||
protected ContentFolder _folder;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this node can be deleted.
|
||||
/// </summary>
|
||||
public virtual bool CanDelete => true;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this node can be duplicated.
|
||||
/// </summary>
|
||||
public virtual bool CanDuplicate => true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content folder item.
|
||||
/// </summary>
|
||||
@@ -302,7 +312,7 @@ namespace FlaxEditor.Content
|
||||
StartRenaming();
|
||||
return true;
|
||||
case KeyboardKeys.Delete:
|
||||
if (Folder.Exists)
|
||||
if (Folder.Exists && CanDelete)
|
||||
Editor.Instance.Windows.ContentWin.Delete(Folder);
|
||||
return true;
|
||||
}
|
||||
@@ -311,7 +321,7 @@ namespace FlaxEditor.Content
|
||||
switch (key)
|
||||
{
|
||||
case KeyboardKeys.D:
|
||||
if (Folder.Exists)
|
||||
if (Folder.Exists && CanDuplicate)
|
||||
Editor.Instance.Windows.ContentWin.Duplicate(Folder);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,12 @@ namespace FlaxEditor.Content
|
||||
{
|
||||
private FileSystemWatcher _watcher;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanDelete => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanDuplicate => false;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MainContentTreeNode"/> class.
|
||||
/// </summary>
|
||||
|
||||
@@ -114,18 +114,32 @@ namespace FlaxEditor.Windows
|
||||
}
|
||||
}
|
||||
|
||||
cm.AddButton("Delete", () => Delete(item));
|
||||
if (isFolder && folder.Node is MainContentTreeNode)
|
||||
{
|
||||
cm.AddSeparator();
|
||||
}
|
||||
else
|
||||
{
|
||||
cm.AddButton("Delete", () => Delete(item));
|
||||
|
||||
cm.AddSeparator();
|
||||
cm.AddSeparator();
|
||||
|
||||
cm.AddButton("Duplicate", _view.Duplicate);
|
||||
cm.AddButton("Duplicate", _view.Duplicate);
|
||||
|
||||
cm.AddButton("Copy", _view.Copy);
|
||||
cm.AddButton("Copy", _view.Copy);
|
||||
}
|
||||
|
||||
b = cm.AddButton("Paste", _view.Paste);
|
||||
b.Enabled = _view.CanPaste();
|
||||
|
||||
cm.AddButton("Rename", () => Rename(item));
|
||||
if (isFolder && folder.Node is MainContentTreeNode)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
cm.AddButton("Rename", () => Rename(item));
|
||||
}
|
||||
|
||||
// Custom options
|
||||
ContextMenuShow?.Invoke(cm, item);
|
||||
|
||||
@@ -25,6 +25,19 @@ private:
|
||||
int32 _capacity;
|
||||
AllocationData _allocation;
|
||||
|
||||
FORCE_INLINE static void MoveToEmpty(AllocationData& to, AllocationData& from, int32 fromCount, int32 fromCapacity)
|
||||
{
|
||||
if IF_CONSTEXPR (AllocationType::HasSwap)
|
||||
to.Swap(from);
|
||||
else
|
||||
{
|
||||
to.Allocate(fromCapacity);
|
||||
Memory::MoveItems(to.Get(), from.Get(), fromCount);
|
||||
Memory::DestructItems(from.Get(), fromCount);
|
||||
from.Free();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Array"/> class.
|
||||
@@ -134,7 +147,7 @@ public:
|
||||
_capacity = other._capacity;
|
||||
other._count = 0;
|
||||
other._capacity = 0;
|
||||
_allocation.Swap(other._allocation);
|
||||
MoveToEmpty(_allocation, other._allocation, _count, _capacity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -191,7 +204,7 @@ public:
|
||||
_capacity = other._capacity;
|
||||
other._count = 0;
|
||||
other._capacity = 0;
|
||||
_allocation.Swap(other._allocation);
|
||||
MoveToEmpty(_allocation, other._allocation, _count, _capacity);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -713,9 +726,18 @@ public:
|
||||
/// <param name="other">The other collection.</param>
|
||||
void Swap(Array& other)
|
||||
{
|
||||
::Swap(_count, other._count);
|
||||
::Swap(_capacity, other._capacity);
|
||||
_allocation.Swap(other._allocation);
|
||||
if IF_CONSTEXPR (AllocationType::HasSwap)
|
||||
{
|
||||
_allocation.Swap(other._allocation);
|
||||
::Swap(_count, other._count);
|
||||
::Swap(_capacity, other._capacity);
|
||||
}
|
||||
else
|
||||
{
|
||||
Array tmp = MoveTemp(other);
|
||||
other = *this;
|
||||
*this = MoveTemp(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -726,9 +748,7 @@ public:
|
||||
T* data = _allocation.Get();
|
||||
const int32 count = _count / 2;
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
::Swap(data[i], data[_count - i - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
@@ -110,6 +110,33 @@ private:
|
||||
int32 _size = 0;
|
||||
AllocationData _allocation;
|
||||
|
||||
FORCE_INLINE static void MoveToEmpty(AllocationData& to, AllocationData& from, int32 fromSize)
|
||||
{
|
||||
if IF_CONSTEXPR (AllocationType::HasSwap)
|
||||
to.Swap(from);
|
||||
else
|
||||
{
|
||||
to.Allocate(fromSize);
|
||||
Bucket* toData = to.Get();
|
||||
Bucket* fromData = from.Get();
|
||||
for (int32 i = 0; i < fromSize; i++)
|
||||
{
|
||||
Bucket& fromBucket = fromData[i];
|
||||
if (fromBucket.IsOccupied())
|
||||
{
|
||||
Bucket& toBucket = toData[i];
|
||||
Memory::MoveItems(&toBucket.Key, &fromBucket.Key, 1);
|
||||
Memory::MoveItems(&toBucket.Value, &fromBucket.Value, 1);
|
||||
toBucket._state = Bucket::Occupied;
|
||||
Memory::DestructItem(&fromBucket.Key);
|
||||
Memory::DestructItem(&fromBucket.Value);
|
||||
fromBucket._state = Bucket::Empty;
|
||||
}
|
||||
}
|
||||
from.Free();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Dictionary"/> class.
|
||||
@@ -139,7 +166,7 @@ public:
|
||||
other._elementsCount = 0;
|
||||
other._deletedCount = 0;
|
||||
other._size = 0;
|
||||
_allocation.Swap(other._allocation);
|
||||
MoveToEmpty(_allocation, other._allocation, _size);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -180,7 +207,7 @@ public:
|
||||
other._elementsCount = 0;
|
||||
other._deletedCount = 0;
|
||||
other._size = 0;
|
||||
_allocation.Swap(other._allocation);
|
||||
MoveToEmpty(_allocation, other._allocation, _size);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -510,7 +537,7 @@ public:
|
||||
return;
|
||||
ASSERT(capacity >= 0);
|
||||
AllocationData oldAllocation;
|
||||
oldAllocation.Swap(_allocation);
|
||||
MoveToEmpty(oldAllocation, _allocation, _size);
|
||||
const int32 oldSize = _size;
|
||||
const int32 oldElementsCount = _elementsCount;
|
||||
_deletedCount = _elementsCount = 0;
|
||||
@@ -580,10 +607,19 @@ public:
|
||||
/// <param name="other">The other collection.</param>
|
||||
void Swap(Dictionary& other)
|
||||
{
|
||||
::Swap(_elementsCount, other._elementsCount);
|
||||
::Swap(_deletedCount, other._deletedCount);
|
||||
::Swap(_size, other._size);
|
||||
_allocation.Swap(other._allocation);
|
||||
if IF_CONSTEXPR (AllocationType::HasSwap)
|
||||
{
|
||||
::Swap(_elementsCount, other._elementsCount);
|
||||
::Swap(_deletedCount, other._deletedCount);
|
||||
::Swap(_size, other._size);
|
||||
_allocation.Swap(other._allocation);
|
||||
}
|
||||
else
|
||||
{
|
||||
Dictionary tmp = MoveTemp(other);
|
||||
other = *this;
|
||||
*this = MoveTemp(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -930,7 +966,7 @@ private:
|
||||
{
|
||||
// Rebuild entire table completely
|
||||
AllocationData oldAllocation;
|
||||
oldAllocation.Swap(_allocation);
|
||||
MoveToEmpty(oldAllocation, _allocation, _size);
|
||||
_allocation.Allocate(_size);
|
||||
Bucket* data = _allocation.Get();
|
||||
for (int32 i = 0; i < _size; i++)
|
||||
|
||||
@@ -93,6 +93,31 @@ private:
|
||||
int32 _size = 0;
|
||||
AllocationData _allocation;
|
||||
|
||||
FORCE_INLINE static void MoveToEmpty(AllocationData& to, AllocationData& from, int32 fromSize)
|
||||
{
|
||||
if IF_CONSTEXPR (AllocationType::HasSwap)
|
||||
to.Swap(from);
|
||||
else
|
||||
{
|
||||
to.Allocate(fromSize);
|
||||
Bucket* toData = to.Get();
|
||||
Bucket* fromData = from.Get();
|
||||
for (int32 i = 0; i < fromSize; i++)
|
||||
{
|
||||
Bucket& fromBucket = fromData[i];
|
||||
if (fromBucket.IsOccupied())
|
||||
{
|
||||
Bucket& toBucket = toData[i];
|
||||
Memory::MoveItems(&toBucket.Item, &fromBucket.Item, 1);
|
||||
toBucket._state = Bucket::Occupied;
|
||||
Memory::DestructItem(&fromBucket.Item);
|
||||
fromBucket._state = Bucket::Empty;
|
||||
}
|
||||
}
|
||||
from.Free();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HashSet"/> class.
|
||||
@@ -122,7 +147,7 @@ public:
|
||||
other._elementsCount = 0;
|
||||
other._deletedCount = 0;
|
||||
other._size = 0;
|
||||
_allocation.Swap(other._allocation);
|
||||
MoveToEmpty(_allocation, other._allocation, _size);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -163,7 +188,7 @@ public:
|
||||
other._elementsCount = 0;
|
||||
other._deletedCount = 0;
|
||||
other._size = 0;
|
||||
_allocation.Swap(other._allocation);
|
||||
MoveToEmpty(_allocation, other._allocation, _size);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -389,7 +414,7 @@ public:
|
||||
return;
|
||||
ASSERT(capacity >= 0);
|
||||
AllocationData oldAllocation;
|
||||
oldAllocation.Swap(_allocation);
|
||||
MoveToEmpty(oldAllocation, _allocation, _size);
|
||||
const int32 oldSize = _size;
|
||||
const int32 oldElementsCount = _elementsCount;
|
||||
_deletedCount = _elementsCount = 0;
|
||||
@@ -458,10 +483,19 @@ public:
|
||||
/// <param name="other">The other collection.</param>
|
||||
void Swap(HashSet& other)
|
||||
{
|
||||
::Swap(_elementsCount, other._elementsCount);
|
||||
::Swap(_deletedCount, other._deletedCount);
|
||||
::Swap(_size, other._size);
|
||||
_allocation.Swap(other._allocation);
|
||||
if IF_CONSTEXPR (AllocationType::HasSwap)
|
||||
{
|
||||
::Swap(_elementsCount, other._elementsCount);
|
||||
::Swap(_deletedCount, other._deletedCount);
|
||||
::Swap(_size, other._size);
|
||||
_allocation.Swap(other._allocation);
|
||||
}
|
||||
else
|
||||
{
|
||||
HashSet tmp = MoveTemp(other);
|
||||
other = *this;
|
||||
*this = MoveTemp(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -726,7 +760,7 @@ private:
|
||||
{
|
||||
// Rebuild entire table completely
|
||||
AllocationData oldAllocation;
|
||||
oldAllocation.Swap(_allocation);
|
||||
MoveToEmpty(oldAllocation, _allocation, _size);
|
||||
_allocation.Allocate(_size);
|
||||
Bucket* data = _allocation.Get();
|
||||
for (int32 i = 0; i < _size; i++)
|
||||
|
||||
@@ -93,3 +93,10 @@
|
||||
#endif
|
||||
|
||||
#define PACK_STRUCT(__Declaration__) PACK_BEGIN() __Declaration__ PACK_END()
|
||||
|
||||
// C++ 17
|
||||
#if __cplusplus >= 201703L
|
||||
#define IF_CONSTEXPR constexpr
|
||||
#else
|
||||
#define IF_CONSTEXPR
|
||||
#endif
|
||||
|
||||
@@ -12,6 +12,8 @@ template<int Capacity>
|
||||
class FixedAllocation
|
||||
{
|
||||
public:
|
||||
enum { HasSwap = false };
|
||||
|
||||
template<typename T>
|
||||
class Data
|
||||
{
|
||||
@@ -61,12 +63,9 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
FORCE_INLINE void Swap(Data& other)
|
||||
void Swap(Data& other)
|
||||
{
|
||||
byte tmp[Capacity * sizeof(T)];
|
||||
Platform::MemoryCopy(tmp, _data, Capacity * sizeof(T));
|
||||
Platform::MemoryCopy(_data, other._data, Capacity * sizeof(T));
|
||||
Platform::MemoryCopy(other._data, tmp, Capacity * sizeof(T));
|
||||
// Not supported
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -77,6 +76,8 @@ public:
|
||||
class HeapAllocation
|
||||
{
|
||||
public:
|
||||
enum { HasSwap = true };
|
||||
|
||||
template<typename T>
|
||||
class Data
|
||||
{
|
||||
@@ -179,6 +180,8 @@ template<int Capacity, typename OtherAllocator = HeapAllocation>
|
||||
class InlinedAllocation
|
||||
{
|
||||
public:
|
||||
enum { HasSwap = false };
|
||||
|
||||
template<typename T>
|
||||
class Data
|
||||
{
|
||||
@@ -267,14 +270,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
FORCE_INLINE void Swap(Data& other)
|
||||
void Swap(Data& other)
|
||||
{
|
||||
byte tmp[Capacity * sizeof(T)];
|
||||
Platform::MemoryCopy(tmp, _data, Capacity * sizeof(T));
|
||||
Platform::MemoryCopy(_data, other._data, Capacity * sizeof(T));
|
||||
Platform::MemoryCopy(other._data, tmp, Capacity * sizeof(T));
|
||||
::Swap(_useOther, other._useOther);
|
||||
_other.Swap(other._other);
|
||||
// Not supported
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -522,7 +522,13 @@ void EngineImpl::InitLog()
|
||||
LOG(Info, "Compiled for Dev Environment");
|
||||
#endif
|
||||
LOG(Info, "Version " FLAXENGINE_VERSION_TEXT);
|
||||
LOG(Info, "Compiled: {0} {1}", TEXT(__DATE__), TEXT(__TIME__));
|
||||
const Char* cpp = TEXT("?");
|
||||
if (__cplusplus == 202101L) cpp = TEXT("C++23");
|
||||
else if (__cplusplus == 202002L) cpp = TEXT("C++20");
|
||||
else if (__cplusplus == 201703L) cpp = TEXT("C++17");
|
||||
else if (__cplusplus == 201402L) cpp = TEXT("C++14");
|
||||
else if (__cplusplus == 201103L) cpp = TEXT("C++11");
|
||||
LOG(Info, "Compiled: {0} {1} {2}", TEXT(__DATE__), TEXT(__TIME__), cpp);
|
||||
#ifdef _MSC_VER
|
||||
const String mcsVer = StringUtils::ToString(_MSC_FULL_VER);
|
||||
LOG(Info, "Compiled with Visual C++ {0}.{1}.{2}.{3:0^2d}", mcsVer.Substring(0, 2), mcsVer.Substring(2, 2), mcsVer.Substring(4, 5), _MSC_BUILD);
|
||||
|
||||
@@ -1271,6 +1271,9 @@ namespace FlaxEngine.Interop
|
||||
case Type _ when type == typeof(IntPtr):
|
||||
monoType = MTypes.Ptr;
|
||||
break;
|
||||
case Type _ when type.IsPointer:
|
||||
monoType = MTypes.Ptr;
|
||||
break;
|
||||
case Type _ when type.IsEnum:
|
||||
monoType = MTypes.Enum;
|
||||
break;
|
||||
|
||||
@@ -1112,11 +1112,9 @@ namespace FlaxEngine.Interop
|
||||
|
||||
internal static void ToManagedPointer(ref IntPtr managedValue, IntPtr nativePtr, bool byRef)
|
||||
{
|
||||
Type type = typeof(T);
|
||||
byRef |= type.IsByRef; // Is this needed?
|
||||
if (type.IsByRef)
|
||||
Assert.IsTrue(type.GetElementType().IsValueType);
|
||||
managedValue = byRef ? nativePtr : Unsafe.Read<IntPtr>(nativePtr.ToPointer());
|
||||
if (byRef)
|
||||
nativePtr = Unsafe.Read<IntPtr>(nativePtr.ToPointer());
|
||||
managedValue = nativePtr;
|
||||
}
|
||||
|
||||
internal static void ToManagedHandle(ref ManagedHandle managedValue, IntPtr nativePtr, bool byRef)
|
||||
@@ -1135,7 +1133,7 @@ namespace FlaxEngine.Interop
|
||||
marshallers[i](fields[i], offsets[i], ref managedValue, fieldPtr, out int fieldSize);
|
||||
fieldPtr += fieldSize;
|
||||
}
|
||||
Assert.IsTrue((fieldPtr - nativePtr) <= Unsafe.SizeOf<T>());
|
||||
//Assert.IsTrue((fieldPtr - nativePtr) <= GetTypeSize(typeof(T)));
|
||||
}
|
||||
|
||||
internal static void ToManaged(ref T managedValue, IntPtr nativePtr, bool byRef)
|
||||
@@ -1182,7 +1180,7 @@ namespace FlaxEngine.Interop
|
||||
marshallers[i](fields[i], offsets[i], ref managedValue, nativePtr, out int fieldSize);
|
||||
nativePtr += fieldSize;
|
||||
}
|
||||
Assert.IsTrue((nativePtr - fieldPtr) <= Unsafe.SizeOf<T>());
|
||||
//Assert.IsTrue((nativePtr - fieldPtr) <= GetTypeSize(typeof(T)));
|
||||
}
|
||||
|
||||
internal static void ToNative(ref T managedValue, IntPtr nativePtr)
|
||||
@@ -1580,7 +1578,7 @@ namespace FlaxEngine.Interop
|
||||
private static IntPtr PinValue<T>(T value) where T : struct
|
||||
{
|
||||
// Store the converted value in unmanaged memory so it will not be relocated by the garbage collector.
|
||||
int size = Unsafe.SizeOf<T>();
|
||||
int size = GetTypeSize(typeof(T));
|
||||
uint index = Interlocked.Increment(ref pinnedAllocationsPointer) % (uint)pinnedAllocations.Length;
|
||||
ref (IntPtr ptr, int size) alloc = ref pinnedAllocations[index];
|
||||
if (alloc.size < size)
|
||||
|
||||
@@ -63,7 +63,6 @@ StreamingTexture::~StreamingTexture()
|
||||
{
|
||||
UnloadTexture();
|
||||
SAFE_DELETE(_texture);
|
||||
ASSERT(_streamingTasks.Count() == 0);
|
||||
}
|
||||
|
||||
Float2 StreamingTexture::Size() const
|
||||
@@ -134,11 +133,9 @@ bool StreamingTexture::Create(const TextureHeader& header)
|
||||
void StreamingTexture::UnloadTexture()
|
||||
{
|
||||
ScopeLock lock(_owner->GetOwnerLocker());
|
||||
|
||||
// Release
|
||||
CancelStreamingTasks();
|
||||
_texture->ReleaseGPU();
|
||||
_header.MipLevels = 0;
|
||||
|
||||
ASSERT(_streamingTasks.Count() == 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ void ENetDriver::Disconnect(const NetworkConnection& connection)
|
||||
}
|
||||
}
|
||||
|
||||
bool ENetDriver::PopEvent(NetworkEvent* eventPtr)
|
||||
bool ENetDriver::PopEvent(NetworkEvent& eventPtr)
|
||||
{
|
||||
ASSERT(_host);
|
||||
ENetEvent event;
|
||||
@@ -173,30 +173,30 @@ bool ENetDriver::PopEvent(NetworkEvent* eventPtr)
|
||||
{
|
||||
// Copy sender data
|
||||
const uint32 connectionId = enet_peer_get_id(event.peer);
|
||||
eventPtr->Sender.ConnectionId = connectionId;
|
||||
eventPtr.Sender.ConnectionId = connectionId;
|
||||
|
||||
switch (event.type)
|
||||
{
|
||||
case ENET_EVENT_TYPE_CONNECT:
|
||||
eventPtr->EventType = NetworkEventType::Connected;
|
||||
eventPtr.EventType = NetworkEventType::Connected;
|
||||
if (IsServer())
|
||||
_peerMap.Add(connectionId, event.peer);
|
||||
break;
|
||||
case ENET_EVENT_TYPE_DISCONNECT:
|
||||
eventPtr->EventType = NetworkEventType::Disconnected;
|
||||
eventPtr.EventType = NetworkEventType::Disconnected;
|
||||
if (IsServer())
|
||||
_peerMap.Remove(connectionId);
|
||||
break;
|
||||
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
|
||||
eventPtr->EventType = NetworkEventType::Timeout;
|
||||
eventPtr.EventType = NetworkEventType::Timeout;
|
||||
if (IsServer())
|
||||
_peerMap.Remove(connectionId);
|
||||
break;
|
||||
case ENET_EVENT_TYPE_RECEIVE:
|
||||
eventPtr->EventType = NetworkEventType::Message;
|
||||
eventPtr->Message = _networkHost->CreateMessage();
|
||||
eventPtr->Message.Length = event.packet->dataLength;
|
||||
Platform::MemoryCopy(eventPtr->Message.Buffer, event.packet->data, event.packet->dataLength);
|
||||
eventPtr.EventType = NetworkEventType::Message;
|
||||
eventPtr.Message = _networkHost->CreateMessage();
|
||||
eventPtr.Message.Length = event.packet->dataLength;
|
||||
Platform::MemoryCopy(eventPtr.Message.Buffer, event.packet->data, event.packet->dataLength);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
bool Connect() override;
|
||||
void Disconnect() override;
|
||||
void Disconnect(const NetworkConnection& connection) override;
|
||||
bool PopEvent(NetworkEvent* eventPtr) override;
|
||||
bool PopEvent(NetworkEvent& eventPtr) override;
|
||||
void SendMessage(NetworkChannelType channelType, const NetworkMessage& message) override;
|
||||
void SendMessage(NetworkChannelType channelType, const NetworkMessage& message, NetworkConnection target) override;
|
||||
void SendMessage(NetworkChannelType channelType, const NetworkMessage& message, const Array<NetworkConnection, HeapAllocation>& targets) override;
|
||||
|
||||
@@ -92,7 +92,7 @@ void NetworkLagDriver::Disconnect(const NetworkConnection& connection)
|
||||
_driver->Disconnect(connection);
|
||||
}
|
||||
|
||||
bool NetworkLagDriver::PopEvent(NetworkEvent* eventPtr)
|
||||
bool NetworkLagDriver::PopEvent(NetworkEvent& eventPtr)
|
||||
{
|
||||
if (!_driver)
|
||||
return false;
|
||||
@@ -104,7 +104,7 @@ bool NetworkLagDriver::PopEvent(NetworkEvent* eventPtr)
|
||||
if (e.Lag > 0.0)
|
||||
continue;
|
||||
|
||||
*eventPtr = e.Event;
|
||||
eventPtr = e.Event;
|
||||
_events.RemoveAtKeepOrder(i);
|
||||
return true;
|
||||
}
|
||||
@@ -117,7 +117,7 @@ bool NetworkLagDriver::PopEvent(NetworkEvent* eventPtr)
|
||||
|
||||
auto& e = _events.AddOne();
|
||||
e.Lag = (double)Lag;
|
||||
e.Event = *eventPtr;
|
||||
e.Event = eventPtr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
bool Connect() override;
|
||||
void Disconnect() override;
|
||||
void Disconnect(const NetworkConnection& connection) override;
|
||||
bool PopEvent(NetworkEvent* eventPtr) override;
|
||||
bool PopEvent(NetworkEvent& eventPtr) override;
|
||||
void SendMessage(NetworkChannelType channelType, const NetworkMessage& message) override;
|
||||
void SendMessage(NetworkChannelType channelType, const NetworkMessage& message, NetworkConnection target) override;
|
||||
void SendMessage(NetworkChannelType channelType, const NetworkMessage& message, const Array<NetworkConnection, HeapAllocation>& targets) override;
|
||||
|
||||
@@ -71,7 +71,7 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="eventPtr">The pointer to event structure.</param>
|
||||
/// <returns>True when succeeded and the event can be processed.</returns>
|
||||
API_FUNCTION() virtual bool PopEvent(NetworkEvent* eventPtr) = 0;
|
||||
API_FUNCTION() virtual bool PopEvent(API_PARAM(Out) NetworkEvent& eventPtr) = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Sends given message over specified channel to the server.
|
||||
|
||||
@@ -10,13 +10,19 @@
|
||||
API_STRUCT(Namespace="FlaxEngine.Networking") struct FLAXENGINE_API NetworkConnection
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkConnection);
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// The identifier of the connection.
|
||||
/// </summary>
|
||||
/// <remarks>Used by network driver implementations.</remarks>
|
||||
API_FIELD()
|
||||
uint32 ConnectionId;
|
||||
API_FIELD() uint32 ConnectionId;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct TIsPODType<NetworkConnection>
|
||||
{
|
||||
enum { Value = true };
|
||||
};
|
||||
|
||||
inline bool operator==(const NetworkConnection& a, const NetworkConnection& b)
|
||||
|
||||
@@ -43,24 +43,28 @@ API_ENUM(Namespace="FlaxEngine.Networking") enum class NetworkEventType
|
||||
API_STRUCT(Namespace="FlaxEngine.Networking") struct FLAXENGINE_API NetworkEvent
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkEvent);
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// The type of the received event.
|
||||
/// </summary>
|
||||
API_FIELD();
|
||||
NetworkEventType EventType;
|
||||
API_FIELD() NetworkEventType EventType;
|
||||
|
||||
/// <summary>
|
||||
/// The message when this event is an "message" event - not valid in any other cases.
|
||||
/// If this is an message-event, make sure to return the message using RecycleMessage function of the peer after processing it!
|
||||
/// </summary>
|
||||
API_FIELD();
|
||||
NetworkMessage Message;
|
||||
API_FIELD() NetworkMessage Message;
|
||||
|
||||
/// <summary>
|
||||
/// The connected of the client that has sent message, connected, disconnected or got a timeout.
|
||||
/// </summary>
|
||||
/// <remarks>Only valid when event has been received on server-peer.</remarks>
|
||||
API_FIELD();
|
||||
NetworkConnection Sender;
|
||||
API_FIELD() NetworkConnection Sender;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct TIsPODType<NetworkEvent>
|
||||
{
|
||||
enum { Value = true };
|
||||
};
|
||||
|
||||
@@ -382,7 +382,8 @@ void NetworkManagerService::Update()
|
||||
|
||||
// Process network messages
|
||||
NetworkEvent event;
|
||||
while (peer->PopEvent(event))
|
||||
bool eventIsValid = true;
|
||||
while (peer->PopEvent(event) && eventIsValid)
|
||||
{
|
||||
switch (event.EventType)
|
||||
{
|
||||
@@ -472,6 +473,9 @@ void NetworkManagerService::Update()
|
||||
}
|
||||
peer->RecycleMessage(event.Message);
|
||||
break;
|
||||
default:
|
||||
eventIsValid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ void NetworkPeer::Disconnect(const NetworkConnection& connection)
|
||||
bool NetworkPeer::PopEvent(NetworkEvent& eventRef)
|
||||
{
|
||||
PROFILE_CPU();
|
||||
return NetworkDriver->PopEvent(&eventRef);
|
||||
return NetworkDriver->PopEvent(eventRef);
|
||||
}
|
||||
|
||||
NetworkMessage NetworkPeer::CreateMessage()
|
||||
|
||||
@@ -37,30 +37,26 @@ public:
|
||||
/// Once this is called, this peer becomes a server.
|
||||
/// </summary>
|
||||
/// <returns>True when succeeded.</returns>
|
||||
API_FUNCTION()
|
||||
bool Listen();
|
||||
API_FUNCTION() bool Listen();
|
||||
|
||||
/// <summary>
|
||||
/// Starts connection handshake with the end point specified in the <seealso cref="NetworkConfig"/> structure.
|
||||
/// Once this is called, this peer becomes a client.
|
||||
/// </summary>
|
||||
/// <returns>True when succeeded.</returns>
|
||||
API_FUNCTION()
|
||||
bool Connect();
|
||||
API_FUNCTION() bool Connect();
|
||||
|
||||
/// <summary>
|
||||
/// Disconnects from the server.
|
||||
/// </summary>
|
||||
/// <remarks>Can be used only by the client!</remarks>
|
||||
API_FUNCTION()
|
||||
void Disconnect();
|
||||
API_FUNCTION() void Disconnect();
|
||||
|
||||
/// <summary>
|
||||
/// Disconnects given connection from the server.
|
||||
/// </summary>
|
||||
/// <remarks>Can be used only by the server!</remarks>
|
||||
API_FUNCTION()
|
||||
void Disconnect(const NetworkConnection& connection);
|
||||
API_FUNCTION() void Disconnect(const NetworkConnection& connection);
|
||||
|
||||
/// <summary>
|
||||
/// Tries to pop an network event from the queue.
|
||||
@@ -68,8 +64,7 @@ public:
|
||||
/// <param name="eventRef">The reference to event structure.</param>
|
||||
/// <returns>True when succeeded and the event can be processed.</returns>
|
||||
/// <remarks>If this returns message event, make sure to recycle the message using <see cref="RecycleMessage"/> function after processing it!</remarks>
|
||||
API_FUNCTION()
|
||||
bool PopEvent(API_PARAM(out) NetworkEvent& eventRef);
|
||||
API_FUNCTION() bool PopEvent(API_PARAM(Out) NetworkEvent& eventRef);
|
||||
|
||||
/// <summary>
|
||||
/// Acquires new message from the pool.
|
||||
@@ -77,29 +72,25 @@ public:
|
||||
/// </summary>
|
||||
/// <returns>The acquired message.</returns>
|
||||
/// <remarks>Make sure to recycle the message to this peer once it is no longer needed!</remarks>
|
||||
API_FUNCTION()
|
||||
NetworkMessage CreateMessage();
|
||||
API_FUNCTION() NetworkMessage CreateMessage();
|
||||
|
||||
/// <summary>
|
||||
/// Returns given message to the pool.
|
||||
/// </summary>
|
||||
/// <remarks>Make sure that this message belongs to the peer and has not been recycled already (debug build checks for this)!</remarks>
|
||||
API_FUNCTION()
|
||||
void RecycleMessage(const NetworkMessage& message);
|
||||
API_FUNCTION() void RecycleMessage(const NetworkMessage& message);
|
||||
|
||||
/// <summary>
|
||||
/// Acquires new message from the pool and setups it for sending.
|
||||
/// </summary>
|
||||
/// <returns>The acquired message.</returns>
|
||||
API_FUNCTION()
|
||||
NetworkMessage BeginSendMessage();
|
||||
API_FUNCTION() NetworkMessage BeginSendMessage();
|
||||
|
||||
/// <summary>
|
||||
/// Aborts given message send. This effectively deinitializes the message and returns it to the pool.
|
||||
/// </summary>
|
||||
/// <param name="message">The message.</param>
|
||||
API_FUNCTION()
|
||||
void AbortSendMessage(const NetworkMessage& message);
|
||||
API_FUNCTION() void AbortSendMessage(const NetworkMessage& message);
|
||||
|
||||
/// <summary>
|
||||
/// Sends given message over specified channel to the server.
|
||||
@@ -111,8 +102,7 @@ public:
|
||||
/// Do not recycle the message after calling this.
|
||||
/// This function automatically recycles the message.
|
||||
/// </remarks>
|
||||
API_FUNCTION()
|
||||
bool EndSendMessage(NetworkChannelType channelType, const NetworkMessage& message);
|
||||
API_FUNCTION() bool EndSendMessage(NetworkChannelType channelType, const NetworkMessage& message);
|
||||
|
||||
/// <summary>
|
||||
/// Sends given message over specified channel to the given client connection (target).
|
||||
@@ -125,8 +115,7 @@ public:
|
||||
/// Do not recycle the message after calling this.
|
||||
/// This function automatically recycles the message.
|
||||
/// </remarks>
|
||||
API_FUNCTION()
|
||||
bool EndSendMessage(NetworkChannelType channelType, const NetworkMessage& message, const NetworkConnection& target);
|
||||
API_FUNCTION() bool EndSendMessage(NetworkChannelType channelType, const NetworkMessage& message, const NetworkConnection& target);
|
||||
|
||||
/// <summary>
|
||||
/// Sends given message over specified channel to the given client connection (target).
|
||||
@@ -139,8 +128,7 @@ public:
|
||||
/// Do not recycle the message after calling this.
|
||||
/// This function automatically recycles the message.
|
||||
/// </remarks>
|
||||
API_FUNCTION()
|
||||
bool EndSendMessage(NetworkChannelType channelType, const NetworkMessage& message, const Array<NetworkConnection, HeapAllocation>& targets);
|
||||
API_FUNCTION() bool EndSendMessage(NetworkChannelType channelType, const NetworkMessage& message, const Array<NetworkConnection, HeapAllocation>& targets);
|
||||
|
||||
/// <summary>
|
||||
/// Creates new peer using given configuration.
|
||||
@@ -148,15 +136,13 @@ public:
|
||||
/// <param name="config">The configuration to create and setup new peer.</param>
|
||||
/// <returns>The peer.</returns>
|
||||
/// <remarks>Peer should be destroyed using <see cref="ShutdownPeer"/> once it is no longer in use. Returns null if failed to create a peer (eg. config is invalid).</remarks>
|
||||
API_FUNCTION()
|
||||
static NetworkPeer* CreatePeer(const NetworkConfig& config);
|
||||
API_FUNCTION() static NetworkPeer* CreatePeer(const NetworkConfig& config);
|
||||
|
||||
/// <summary>
|
||||
/// Shutdowns and destroys given peer.
|
||||
/// </summary>
|
||||
/// <param name="peer">The peer to destroy.</param>
|
||||
API_FUNCTION()
|
||||
static void ShutdownPeer(NetworkPeer* peer);
|
||||
API_FUNCTION() static void ShutdownPeer(NetworkPeer* peer);
|
||||
|
||||
public:
|
||||
bool IsValid() const
|
||||
|
||||
@@ -11,6 +11,8 @@ public:
|
||||
static FLAXENGINE_API void* Allocate(uintptr size);
|
||||
static FLAXENGINE_API void Free(void* ptr, uintptr size);
|
||||
|
||||
enum { HasSwap = true };
|
||||
|
||||
template<typename T>
|
||||
class Data
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@ private:
|
||||
#elif USE_NETCORE
|
||||
void* _handle;
|
||||
StringAnsi _name;
|
||||
StringAnsi _namespace_;
|
||||
StringAnsi _namespace;
|
||||
uint32 _types = 0;
|
||||
mutable uint32 _size = 0;
|
||||
#endif
|
||||
|
||||
@@ -1208,6 +1208,10 @@ void* MUtils::VariantToManagedArgPtr(Variant& value, MType* type, bool& failed)
|
||||
object = nullptr;
|
||||
return object;
|
||||
}
|
||||
case MTypes::Ptr:
|
||||
if (value.Type.Type == VariantType::Null)
|
||||
return nullptr;
|
||||
return (void*)value;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ struct MConverter<String>
|
||||
{
|
||||
MString** dataPtr = MCore::Array::GetAddress<MString*>(data);
|
||||
for (int32 i = 0; i < result.Length(); i++)
|
||||
MUtils::ToString(dataPtr[i], result[i]);
|
||||
MUtils::ToString(dataPtr[i], result.Get()[i]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -151,7 +151,7 @@ struct MConverter<StringAnsi>
|
||||
{
|
||||
MString** dataPtr = MCore::Array::GetAddress<MString*>(data);
|
||||
for (int32 i = 0; i < result.Length(); i++)
|
||||
MUtils::ToString(dataPtr[i], result[i]);
|
||||
MUtils::ToString(dataPtr[i], result.Get()[i]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -184,7 +184,7 @@ struct MConverter<StringView>
|
||||
{
|
||||
MString** dataPtr = MCore::Array::GetAddress<MString*>(data);
|
||||
for (int32 i = 0; i < result.Length(); i++)
|
||||
MUtils::ToString(dataPtr[i], result[i]);
|
||||
MUtils::ToString(dataPtr[i], result.Get()[i]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -217,7 +217,7 @@ struct MConverter<Variant>
|
||||
{
|
||||
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
||||
for (int32 i = 0; i < result.Length(); i++)
|
||||
result[i] = MUtils::UnboxVariant(dataPtr[i]);
|
||||
result.Get()[i] = MUtils::UnboxVariant(dataPtr[i]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -250,7 +250,7 @@ struct MConverter<T*, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Va
|
||||
{
|
||||
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
||||
for (int32 i = 0; i < result.Length(); i++)
|
||||
result[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
||||
result.Get()[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -307,7 +307,7 @@ struct MConverter<ScriptingObjectReference<T>>
|
||||
{
|
||||
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
||||
for (int32 i = 0; i < result.Length(); i++)
|
||||
result[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
||||
result.Get()[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -343,7 +343,7 @@ struct MConverter<AssetReference<T>>
|
||||
{
|
||||
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
||||
for (int32 i = 0; i < result.Length(); i++)
|
||||
result[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
||||
result.Get()[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -836,7 +836,7 @@ bool MAssembly::UnloadImage(bool isReloading)
|
||||
MClass::MClass(const MAssembly* parentAssembly, void* handle, const char* name, const char* fullname, const char* namespace_, MTypeAttributes attributes)
|
||||
: _handle(handle)
|
||||
, _name(name)
|
||||
, _namespace_(namespace_)
|
||||
, _namespace(namespace_)
|
||||
, _assembly(parentAssembly)
|
||||
, _fullname(fullname)
|
||||
, _hasCachedProperties(false)
|
||||
@@ -915,7 +915,7 @@ StringAnsiView MClass::GetName() const
|
||||
|
||||
StringAnsiView MClass::GetNamespace() const
|
||||
{
|
||||
return _namespace_;
|
||||
return _namespace;
|
||||
}
|
||||
|
||||
MType* MClass::GetType() const
|
||||
|
||||
@@ -20,10 +20,7 @@ public class Scripting : EngineModule
|
||||
void AddFrameworkDefines(string template, int major, int latestMinor)
|
||||
{
|
||||
for (int minor = latestMinor; minor >= 0; minor--)
|
||||
{
|
||||
options.ScriptingAPI.Defines.Add(string.Format(template, major, minor));
|
||||
options.ScriptingAPI.Defines.Add(string.Format($"{template}_OR_GREATER", major, minor));
|
||||
}
|
||||
}
|
||||
|
||||
// .NET
|
||||
@@ -31,14 +28,15 @@ public class Scripting : EngineModule
|
||||
options.ScriptingAPI.Defines.Add("USE_NETCORE");
|
||||
|
||||
// .NET SDK
|
||||
AddFrameworkDefines("NET{0}_{1}", 7, 0); // "NET7_0" and "NET7_0_OR_GREATER"
|
||||
AddFrameworkDefines("NET{0}_{1}", 6, 0);
|
||||
AddFrameworkDefines("NET{0}_{1}", 5, 0);
|
||||
var dotnetSdk = DotNetSdk.Instance;
|
||||
options.ScriptingAPI.Defines.Add("NET");
|
||||
AddFrameworkDefines("NETCOREAPP{0}_{1}", 3, 1); // "NETCOREAPP3_1" and "NETCOREAPP3_1_OR_GREATER"
|
||||
AddFrameworkDefines("NETCOREAPP{0}_{1}", 2, 2);
|
||||
AddFrameworkDefines("NETCOREAPP{0}_{1}", 1, 1);
|
||||
AddFrameworkDefines("NET{0}_{1}", dotnetSdk.Version.Major, 0); // "NET7_0"
|
||||
for (int i = 5; i <= dotnetSdk.Version.Major; i++)
|
||||
AddFrameworkDefines("NET{0}_{1}_OR_GREATER", dotnetSdk.Version.Major, 0); // "NET7_0_OR_GREATER"
|
||||
options.ScriptingAPI.Defines.Add("NETCOREAPP");
|
||||
AddFrameworkDefines("NETCOREAPP{0}_{1}_OR_GREATER", 3, 1); // "NETCOREAPP3_1_OR_GREATER"
|
||||
AddFrameworkDefines("NETCOREAPP{0}_{1}_OR_GREATER", 2, 2);
|
||||
AddFrameworkDefines("NETCOREAPP{0}_{1}_OR_GREATER", 1, 1);
|
||||
|
||||
if (options.Target is EngineTarget engineTarget && engineTarget.UseSeparateMainExecutable(options))
|
||||
{
|
||||
|
||||
@@ -441,6 +441,23 @@ void MaterialGenerator::ProcessGroupTextures(Box* box, Node* node, Value& value)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Channel masking
|
||||
switch (box->ID)
|
||||
{
|
||||
case 2:
|
||||
value = value.GetX();
|
||||
break;
|
||||
case 3:
|
||||
value = value.GetY();
|
||||
break;
|
||||
case 4:
|
||||
value = value.GetZ();
|
||||
break;
|
||||
case 5:
|
||||
value = value.GetW();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Scene Color
|
||||
|
||||
@@ -271,6 +271,48 @@ ShaderGraphValue ShaderGraphValue::InitForOne(VariantType::Types type)
|
||||
return ShaderGraphValue(type, String(v));
|
||||
}
|
||||
|
||||
ShaderGraphValue ShaderGraphValue::GetY() const
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case VariantType::Float2:
|
||||
case VariantType::Float3:
|
||||
case VariantType::Float4:
|
||||
case VariantType::Double2:
|
||||
case VariantType::Double3:
|
||||
case VariantType::Double4:
|
||||
return ShaderGraphValue(VariantType::Types::Float, Value + _subs[1]);
|
||||
default:
|
||||
return Zero;
|
||||
}
|
||||
}
|
||||
|
||||
ShaderGraphValue ShaderGraphValue::GetZ() const
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case VariantType::Float3:
|
||||
case VariantType::Float4:
|
||||
case VariantType::Double3:
|
||||
case VariantType::Double4:
|
||||
return ShaderGraphValue(VariantType::Types::Float, Value + _subs[2]);
|
||||
default:
|
||||
return Zero;
|
||||
}
|
||||
}
|
||||
|
||||
ShaderGraphValue ShaderGraphValue::GetW() const
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case VariantType::Float4:
|
||||
case VariantType::Double4:
|
||||
return ShaderGraphValue(VariantType::Types::Float, Value + _subs[3]);
|
||||
default:
|
||||
return One;
|
||||
}
|
||||
}
|
||||
|
||||
ShaderGraphValue ShaderGraphValue::Cast(const ShaderGraphValue& v, VariantType::Types to)
|
||||
{
|
||||
// If they are the same types or input value is empty, then just return value
|
||||
|
||||
@@ -318,28 +318,19 @@ public:
|
||||
/// Gets the Y component of the value. Valid only for vector types.
|
||||
/// </summary>
|
||||
/// <returns>The Y component.</returns>
|
||||
ShaderGraphValue GetY() const
|
||||
{
|
||||
return ShaderGraphValue(VariantType::Types::Float, Value + _subs[1]);
|
||||
}
|
||||
ShaderGraphValue GetY() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Z component of the value. Valid only for vector types.
|
||||
/// </summary>
|
||||
/// <returns>The Z component.</returns>
|
||||
ShaderGraphValue GetZ() const
|
||||
{
|
||||
return ShaderGraphValue(VariantType::Types::Float, Value + _subs[2]);
|
||||
}
|
||||
ShaderGraphValue GetZ() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the W component of the value. Valid only for vector types.
|
||||
/// </summary>
|
||||
/// <returns>The W component.</returns>
|
||||
ShaderGraphValue GetW() const
|
||||
{
|
||||
return ShaderGraphValue(VariantType::Types::Float, Value + _subs[3]);
|
||||
}
|
||||
ShaderGraphValue GetW() const;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
|
||||
@@ -1532,9 +1532,7 @@ namespace Flax.Build.Bindings
|
||||
if (paramIsRef && !parameterInfo.Type.IsConst)
|
||||
{
|
||||
// Unbox from MObject*
|
||||
parameterInfo.Type.IsRef = false;
|
||||
contents.Append($" {parameterInfo.Name} = MUtils::Unbox<{parameterInfo.Type}>(*(MObject**)params[{i}]);").AppendLine();
|
||||
parameterInfo.Type.IsRef = true;
|
||||
contents.Append($" {parameterInfo.Name} = MUtils::Unbox<{parameterInfo.Type.ToString(false)}>(*(MObject**)params[{i}]);").AppendLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1559,8 +1557,7 @@ namespace Flax.Build.Bindings
|
||||
for (var i = 0; i < functionInfo.Parameters.Count; i++)
|
||||
{
|
||||
var parameterInfo = functionInfo.Parameters[i];
|
||||
var paramIsRef = parameterInfo.IsRef || parameterInfo.IsOut;
|
||||
if (paramIsRef && !parameterInfo.Type.IsConst)
|
||||
if ((parameterInfo.IsRef || parameterInfo.IsOut) && !parameterInfo.Type.IsConst)
|
||||
{
|
||||
// Direct value convert
|
||||
var managedToNative = GenerateCppWrapperManagedToNative(buildData, parameterInfo.Type, classInfo, out var managedType, out var apiType, null, out _);
|
||||
@@ -2007,8 +2004,7 @@ namespace Flax.Build.Bindings
|
||||
for (var i = 0; i < paramsCount; i++)
|
||||
{
|
||||
var paramType = eventInfo.Type.GenericArgs[i];
|
||||
var paramIsRef = paramType.IsRef && !paramType.IsConst;
|
||||
if (paramIsRef)
|
||||
if (paramType.IsRef && !paramType.IsConst)
|
||||
{
|
||||
// Convert value back from managed to native (could be modified there)
|
||||
paramType.IsRef = false;
|
||||
@@ -2569,6 +2565,18 @@ namespace Flax.Build.Bindings
|
||||
contents.AppendLine(" {");
|
||||
contents.AppendLine(" Variant __result;");
|
||||
contents.AppendLine($" typeHandle.Module->InvokeMethod(method, Object, Span<Variant>(parameters, {functionInfo.Parameters.Count}), __result);");
|
||||
|
||||
// Convert parameter values back from scripting to native (could be modified there)
|
||||
for (var i = 0; i < functionInfo.Parameters.Count; i++)
|
||||
{
|
||||
var parameterInfo = functionInfo.Parameters[i];
|
||||
var paramIsRef = parameterInfo.IsRef || parameterInfo.IsOut;
|
||||
if (paramIsRef && !parameterInfo.Type.IsConst)
|
||||
{
|
||||
contents.AppendLine($" {parameterInfo.Name} = {GenerateCppWrapperVariantToNative(buildData, parameterInfo.Type, interfaceInfo, $"parameters[{i}]")};");
|
||||
}
|
||||
}
|
||||
|
||||
if (functionInfo.ReturnType.IsVoid)
|
||||
contents.AppendLine(" return;");
|
||||
else
|
||||
@@ -2767,11 +2775,12 @@ namespace Flax.Build.Bindings
|
||||
// Variant converting helper methods
|
||||
foreach (var typeInfo in CppVariantToTypes)
|
||||
{
|
||||
var name = typeInfo.ToString(false);
|
||||
header.AppendLine();
|
||||
header.AppendLine("namespace {");
|
||||
header.Append($"{typeInfo} VariantTo{GenerateCppWrapperNativeToVariantMethodName(typeInfo)}(const Variant& v)").AppendLine();
|
||||
header.Append($"{name} VariantTo{GenerateCppWrapperNativeToVariantMethodName(typeInfo)}(const Variant& v)").AppendLine();
|
||||
header.Append('{').AppendLine();
|
||||
header.Append($" {typeInfo} result;").AppendLine();
|
||||
header.Append($" {name} result;").AppendLine();
|
||||
if (typeInfo.Type == "Array" && typeInfo.GenericArgs != null)
|
||||
{
|
||||
header.Append(" const auto* array = reinterpret_cast<const Array<Variant, HeapAllocation>*>(v.AsData);").AppendLine();
|
||||
|
||||
@@ -180,7 +180,7 @@ namespace Flax.Build.Bindings
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
public string ToString(bool canRef = true)
|
||||
{
|
||||
var sb = new StringBuilder(64);
|
||||
if (IsConst)
|
||||
@@ -199,13 +199,18 @@ namespace Flax.Build.Bindings
|
||||
}
|
||||
if (IsPtr)
|
||||
sb.Append('*');
|
||||
if (IsRef)
|
||||
if (IsRef && canRef)
|
||||
sb.Append('&');
|
||||
if (IsMoveRef)
|
||||
if (IsMoveRef && canRef)
|
||||
sb.Append('&');
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(true);
|
||||
}
|
||||
|
||||
public static bool Equals(List<TypeInfo> a, List<TypeInfo> b)
|
||||
{
|
||||
if (a == null && b == null)
|
||||
|
||||
@@ -247,7 +247,7 @@ namespace Flax.Build
|
||||
args.Add("/fullpaths");
|
||||
args.Add("/filealign:512");
|
||||
#if USE_NETCORE
|
||||
args.Add("/langversion:11.0");
|
||||
args.Add($"/langversion:{dotnetSdk.CSharpLanguageVersion}");
|
||||
args.Add(string.Format("/nullable:{0}", buildOptions.ScriptingAPI.CSharpNullableReferences.ToString().ToLowerInvariant()));
|
||||
if (buildOptions.ScriptingAPI.CSharpNullableReferences == CSharpNullableReferences.Disable)
|
||||
args.Add("-nowarn:8632"); // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
|
||||
|
||||
@@ -161,6 +161,18 @@ namespace Flax.Build
|
||||
/// </summary>
|
||||
public readonly string RuntimeVersionName;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum supported C#-language version for the SDK.
|
||||
/// </summary>
|
||||
public string CSharpLanguageVersion => Version.Major switch
|
||||
{
|
||||
8 => "12.0",
|
||||
7 => "11.0",
|
||||
6 => "10.0",
|
||||
5 => "9.0",
|
||||
_ => "7.3",
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DotNetSdk"/> class.
|
||||
/// </summary>
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
<ErrorReport>none</ErrorReport>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<NoWarn>1701;1702;8981</NoWarn>
|
||||
<RollForward>LatestMajor</RollForward>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -453,6 +453,7 @@ namespace Flax.Build.Platforms
|
||||
commonArgs.Add("/std:c++latest");
|
||||
break;
|
||||
}
|
||||
commonArgs.Add("/Zc:__cplusplus");
|
||||
|
||||
// Generate Intrinsic Functions
|
||||
if (compileEnvironment.IntrinsicFunctions)
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace Flax.Build.Projects.VisualStudio
|
||||
/// <inheritdoc />
|
||||
public override void GenerateProject(Project project, string solutionPath)
|
||||
{
|
||||
var dotnetSdk = DotNetSdk.Instance;
|
||||
var csProjectFileContent = new StringBuilder();
|
||||
|
||||
var vsProject = (VisualStudioProject)project;
|
||||
@@ -73,8 +74,8 @@ namespace Flax.Build.Projects.VisualStudio
|
||||
csProjectFileContent.AppendLine(string.Format(" <Platforms>{0}</Platforms>", string.Join(";", allPlatforms)));
|
||||
|
||||
// Provide default platform and configuration
|
||||
csProjectFileContent.AppendLine(string.Format(" <Configuration Condition=\" '$(Configuration)' == '' \">{0}</Configuration>", defaultConfiguration.Text));
|
||||
csProjectFileContent.AppendLine(string.Format(" <Platform Condition=\" '$(Platform)' == '' \">{0}</Platform>", defaultConfiguration.ArchitectureName));
|
||||
csProjectFileContent.AppendLine(string.Format(" <Configuration>{0}</Configuration>", defaultConfiguration.Text));
|
||||
csProjectFileContent.AppendLine(string.Format(" <Platform>{0}</Platform>", defaultConfiguration.ArchitectureName));
|
||||
|
||||
switch (project.OutputType ?? defaultTarget.OutputType)
|
||||
{
|
||||
@@ -96,7 +97,7 @@ namespace Flax.Build.Projects.VisualStudio
|
||||
var cacheProjectsPath = Utilities.MakePathRelativeTo(Path.Combine(Globals.Root, "Cache", "Projects"), projectDirectory);
|
||||
var flaxBuildTargetsPath = !string.IsNullOrEmpty(cacheProjectsPath) ? Path.Combine(cacheProjectsPath, flaxBuildTargetsFilename) : flaxBuildTargetsFilename;
|
||||
|
||||
csProjectFileContent.AppendLine(" <TargetFramework>net7.0</TargetFramework>");
|
||||
csProjectFileContent.AppendLine($" <TargetFramework>net{dotnetSdk.Version.Major}.{dotnetSdk.Version.Minor}</TargetFramework>");
|
||||
csProjectFileContent.AppendLine(" <ImplicitUsings>disable</ImplicitUsings>");
|
||||
csProjectFileContent.AppendLine(string.Format(" <Nullable>{0}</Nullable>", baseConfiguration.TargetBuildOptions.ScriptingAPI.CSharpNullableReferences.ToString().ToLowerInvariant()));
|
||||
csProjectFileContent.AppendLine(" <IsPackable>false</IsPackable>");
|
||||
@@ -108,7 +109,7 @@ namespace Flax.Build.Projects.VisualStudio
|
||||
csProjectFileContent.AppendLine(" <ProduceReferenceAssembly>false</ProduceReferenceAssembly>");
|
||||
csProjectFileContent.AppendLine(string.Format(" <RootNamespace>{0}</RootNamespace>", project.BaseName));
|
||||
csProjectFileContent.AppendLine(string.Format(" <AssemblyName>{0}.CSharp</AssemblyName>", project.BaseName));
|
||||
csProjectFileContent.AppendLine(" <LangVersion>11.0</LangVersion>");
|
||||
csProjectFileContent.AppendLine($" <LangVersion>{dotnetSdk.CSharpLanguageVersion}</LangVersion>");
|
||||
csProjectFileContent.AppendLine(" <FileAlignment>512</FileAlignment>");
|
||||
|
||||
//csProjectFileContent.AppendLine(" <CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>"); // TODO: use it to reduce burden of framework libs
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<Expand>
|
||||
<Item Name="[Size]" ExcludeView="simple">_count</Item>
|
||||
<Item Name="[Capacity]" ExcludeView="simple">_capacity</Item>
|
||||
<ArrayItems Condition="_count <= _capacity">
|
||||
<ArrayItems Condition="_count <= _capacity">
|
||||
<Size>_count</Size>
|
||||
<ValuePointer>_allocation._data</ValuePointer>
|
||||
</ArrayItems>
|
||||
@@ -153,22 +153,22 @@
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
|
||||
|
||||
<!-- Vector2/Float2/Double2/Int2 -->
|
||||
<Type Name="Vector2Base<*>">
|
||||
<DisplayString>{{ X={X}, Y={Y} }}</DisplayString>
|
||||
</Type>
|
||||
|
||||
|
||||
<!-- Vector3/Float3/Double3/Int3 -->
|
||||
<Type Name="Vector3Base<*>">
|
||||
<DisplayString>{{ X={X}, Y={Y}, Z={Z} }}</DisplayString>
|
||||
</Type>
|
||||
|
||||
|
||||
<!-- Vector4/Float4/Double4/Int4 -->
|
||||
<Type Name="Vector4Base<*>">
|
||||
<DisplayString>{{ X={X}, Y={Y}, Z={Z}, W={W} }}</DisplayString>
|
||||
</Type>
|
||||
|
||||
|
||||
<!-- Quaternion -->
|
||||
<Type Name="Quaternion">
|
||||
<DisplayString>{{ X={X}, Y={Y}, Z={Z}, W={W} }}</DisplayString>
|
||||
@@ -231,7 +231,7 @@
|
||||
<DisplayString>{{ Length={_length} }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[Length]" ExcludeView="simple">_length</Item>
|
||||
<ArrayItems Condition="_data != nullptr">
|
||||
<ArrayItems Condition="_data != nullptr">
|
||||
<Size>_length</Size>
|
||||
<ValuePointer>_data</ValuePointer>
|
||||
</ArrayItems>
|
||||
|
||||
Reference in New Issue
Block a user