Merge branch 'master' into LinuxProcess

This commit is contained in:
nothingTVatYT
2021-10-21 04:14:04 +02:00
committed by GitHub
24 changed files with 282 additions and 134 deletions

View File

@@ -431,6 +431,9 @@ DECLARE_SCRIPTING_TYPE_MINIMAL(BlendingMode);
/// </summary>
API_ENUM() enum class ColorWrite
{
// No color writing.
None = 0,
// Allow data to be stored in the red component.
Red = 1,
// Allow data to be stored in the green component.

View File

@@ -58,8 +58,8 @@ public class Graphics : EngineModule
case TargetPlatform.UWP:
options.PrivateDependencies.Add("GraphicsDeviceDX11");
break;
case TargetPlatform.XboxOne:
case TargetPlatform.XboxScarlett:
case TargetPlatform.XboxOne:
case TargetPlatform.XboxScarlett:
options.PrivateDependencies.Add("GraphicsDeviceDX12");
break;
case TargetPlatform.Linux:

View File

@@ -15,6 +15,7 @@
#include "Engine/Scripting/ScriptingType.h"
#include "Engine/Scripting/BinaryModule.h"
#include "Engine/Profiler/ProfilerCPU.h"
#include "Engine/Serialization/JsonTools.h"
struct AxisEvaluation
{
@@ -105,6 +106,69 @@ void InputSettings::Apply()
Input::AxisMappings = AxisMappings;
}
void InputSettings::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
{
const auto actionMappings = stream.FindMember("ActionMappings");
if (actionMappings != stream.MemberEnd())
{
auto& actionMappingsArray = actionMappings->value;
if (actionMappingsArray.IsArray())
{
ActionMappings.Resize(actionMappingsArray.Size(), false);
for (uint32 i = 0; i < actionMappingsArray.Size(); i++)
{
auto& v = actionMappingsArray[i];
if (!v.IsObject())
continue;
ActionConfig& config = ActionMappings[i];
config.Name = JsonTools::GetString(v, "Name");
config.Mode = JsonTools::GetEnum(v, "Mode", InputActionMode::Pressing);
config.Key = JsonTools::GetEnum(v, "Key", KeyboardKeys::None);
config.MouseButton = JsonTools::GetEnum(v, "MouseButton", MouseButton::None);
config.GamepadButton = JsonTools::GetEnum(v, "GamepadButton", GamepadButton::None);
config.Gamepad = JsonTools::GetEnum(v, "Gamepad", InputGamepadIndex::All);
}
}
else
{
ActionMappings.Resize(0, false);
}
}
const auto axisMappings = stream.FindMember("AxisMappings");
if (axisMappings != stream.MemberEnd())
{
auto& axisMappingsArray = axisMappings->value;
if (axisMappingsArray.IsArray())
{
AxisMappings.Resize(axisMappingsArray.Size(), false);
for (uint32 i = 0; i < axisMappingsArray.Size(); i++)
{
auto& v = axisMappingsArray[i];
if (!v.IsObject())
continue;
AxisConfig& config = AxisMappings[i];
config.Name = JsonTools::GetString(v, "Name");
config.Axis = JsonTools::GetEnum(v, "Axis", InputAxisType::MouseX);
config.Gamepad = JsonTools::GetEnum(v, "Gamepad", InputGamepadIndex::All);
config.PositiveButton = JsonTools::GetEnum(v, "PositiveButton", KeyboardKeys::None);
config.NegativeButton = JsonTools::GetEnum(v, "NegativeButton", KeyboardKeys::None);
config.DeadZone = JsonTools::GetFloat(v, "DeadZone", 0.1f);
config.Sensitivity = JsonTools::GetFloat(v, "Sensitivity", 0.4f);
config.Gravity = JsonTools::GetFloat(v, "Gravity", 1.0f);
config.Scale = JsonTools::GetFloat(v, "Scale", 1.0f);
config.Snap = JsonTools::GetBool(v, "Snap", false);
}
}
else
{
AxisMappings.Resize(0, false);
}
}
}
void Mouse::OnMouseMoved(const Vector2& newPosition)
{
_prevState.MousePosition = newPosition;

View File

@@ -3,7 +3,6 @@
#pragma once
#include "Engine/Core/Config/Settings.h"
#include "Engine/Serialization/JsonTools.h"
#include "VirtualInput.h"
#include "Engine/Core/Collections/Array.h"
@@ -34,59 +33,5 @@ public:
// [SettingsBase]
void Apply() override;
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) final override
{
const auto actionMappings = stream.FindMember("ActionMappings");
if (actionMappings != stream.MemberEnd())
{
auto& actionMappingsArray = actionMappings->value;
ASSERT(actionMappingsArray.IsArray());
ActionMappings.Resize(actionMappingsArray.Size(), false);
for (uint32 i = 0; i < actionMappingsArray.Size(); i++)
{
auto& v = actionMappingsArray[i];
if (!v.IsObject())
continue;
ActionConfig& config = ActionMappings[i];
config.Name = JsonTools::GetString(v, "Name");
config.Mode = JsonTools::GetEnum(v, "Mode", InputActionMode::Pressing);
config.Key = JsonTools::GetEnum(v, "Key", KeyboardKeys::None);
config.MouseButton = JsonTools::GetEnum(v, "MouseButton", MouseButton::None);
config.GamepadButton = JsonTools::GetEnum(v, "GamepadButton", GamepadButton::None);
config.Gamepad = JsonTools::GetEnum(v, "Gamepad", InputGamepadIndex::All);
}
}
const auto axisMappings = stream.FindMember("AxisMappings");
if (axisMappings != stream.MemberEnd())
{
auto& axisMappingsArray = axisMappings->value;
ASSERT(axisMappingsArray.IsArray());
AxisMappings.Resize(axisMappingsArray.Size(), false);
for (uint32 i = 0; i < axisMappingsArray.Size(); i++)
{
auto& v = axisMappingsArray[i];
if (!v.IsObject())
continue;
AxisConfig& config = AxisMappings[i];
config.Name = JsonTools::GetString(v, "Name");
config.Axis = JsonTools::GetEnum(v, "Axis", InputAxisType::MouseX);
config.Gamepad = JsonTools::GetEnum(v, "Gamepad", InputGamepadIndex::All);
config.PositiveButton = JsonTools::GetEnum(v, "PositiveButton", KeyboardKeys::None);
config.NegativeButton = JsonTools::GetEnum(v, "NegativeButton", KeyboardKeys::None);
config.DeadZone = JsonTools::GetFloat(v, "DeadZone", 0.1f);
config.Sensitivity = JsonTools::GetFloat(v, "Sensitivity", 0.4f);
config.Gravity = JsonTools::GetFloat(v, "Gravity", 1.0f);
config.Scale = JsonTools::GetFloat(v, "Scale", 1.0f);
config.Snap = JsonTools::GetBool(v, "Snap", false);
}
}
}
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) final override;
};

View File

@@ -238,6 +238,7 @@ void StaticModel::Draw(RenderContext& renderContext)
SAFE_DELETE_GPU_RESOURCE(vertexColorsBuffer);
}
}
_vertexColorsDirty = false;
}
#if USE_EDITOR

View File

@@ -55,7 +55,7 @@ ENetDriver::ENetDriver(const SpawnParams& params)
{
}
void ENetDriver::Initialize(NetworkPeer* host, const NetworkConfig& config)
bool ENetDriver::Initialize(NetworkPeer* host, const NetworkConfig& config)
{
_networkHost = host;
_config = config;
@@ -64,9 +64,11 @@ void ENetDriver::Initialize(NetworkPeer* host, const NetworkConfig& config)
if (enet_initialize() != 0)
{
LOG(Error, "Failed to initialize ENet driver!");
return true;
}
LOG(Info, "Initialized ENet driver!");
LOG(Info, "Initialized ENet driver");
return false;
}
void ENetDriver::Dispose()

View File

@@ -19,7 +19,8 @@ DECLARE_SCRIPTING_TYPE(ENetDriver);
public:
// [INetworkDriver]
void Initialize(NetworkPeer* host, const NetworkConfig& config) override;
String DriverName() override { return String("ENetDriver"); }
bool Initialize(NetworkPeer* host, const NetworkConfig& config) override;
void Dispose() override;
bool Listen() override;
bool Connect() override;

View File

@@ -3,6 +3,7 @@
#pragma once
#include "Types.h"
#include "Engine/Core/Types/String.h"
#include "Engine/Scripting/ScriptingType.h"
/// <summary>
@@ -18,12 +19,21 @@ public:
/// </summary>
virtual ~INetworkDriver() = default;
/// <summary>
/// Return name of this network driver implementation.
/// </summary>
API_FUNCTION() virtual String DriverName()
{
return String("Unknown");
}
/// <summary>
/// Initializes the instance of this network driver using given configuration.
/// </summary>
/// <param name="host">The peer that this driver has been assigned to.</param>
/// <param name="config">The network config to use to configure this driver.</param>
API_FUNCTION() virtual void Initialize(NetworkPeer* host, const NetworkConfig& config) = 0;
/// <returns>True if failed to initialize network driver, false otherwise.</returns>
API_FUNCTION() virtual bool Initialize(NetworkPeer* host, const NetworkConfig& config) = 0;
/// <summary>
/// Disposes this driver making it no longer usable.

View File

@@ -4,10 +4,12 @@
#include "Engine/Platform/Network.h"
class ScriptingObject;
/// <summary>
/// Network driver implementations enum.
/// </summary>
API_ENUM(Namespace="FlaxEngine.Networking") enum class NetworkDriverType
API_ENUM(Namespace="FlaxEngine.Networking") enum class DEPRECATED NetworkDriverType
{
/// <summary>
/// Invalid network driver implementation.
@@ -26,16 +28,21 @@ API_ENUM(Namespace="FlaxEngine.Networking") enum class NetworkDriverType
API_STRUCT(Namespace="FlaxEngine.Networking") struct FLAXENGINE_API NetworkConfig
{
DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkConfig);
public:
/// <summary>
/// The network driver that will be used to create the peer.
/// To allow two peers to connect, they must use the same host.
/// </summary>
API_FIELD()
NetworkDriverType NetworkDriverType = NetworkDriverType::ENet;
// TODO: Expose INetworkDriver as a ref not enum, when C++/C# interfaces are done.
DEPRECATED NetworkDriverType NetworkDriverType = NetworkDriverType::ENet;
/// <summary>
/// The network driver instance (implements INetworkDriver) that will be used to create and manage the peer, send and receive messages.
/// </summary>
/// <remarks>Object is managed by the created network peer (will be deleted on peer shutdown).</remarks>
API_FIELD()
ScriptingObject* NetworkDriver;
public:
/// <summary>
/// The upper limit on how many peers can join when we're listening.
/// </summary>
@@ -48,21 +55,21 @@ public:
/// <remarks>Set it to "any" when you want to listen at all available addresses.</remarks>
/// <remarks>Only IPv4 is supported.</remarks>
API_FIELD()
String Address = String("127.0.0.1");
String Address = String(TEXT("127.0.0.1"));
/// <summary>
/// The port to connect to or listen at.
/// </summary>
API_FIELD()
uint16 Port = 7777;
/// <summary>
/// The size of a message buffer in bytes.
/// Should be lower than the MTU (maximal transmission unit) - typically 1500 bytes.
/// </summary>
API_FIELD()
uint16 MessageSize = 1500;
/// <summary>
/// The amount of pooled messages that can be used at once (receiving and sending!).
/// </summary>

View File

@@ -2,9 +2,7 @@
#include "NetworkPeer.h"
#include "NetworkEvent.h"
#include "Drivers/ENetDriver.h"
#include "Engine/Core/Log.h"
#include "Engine/Core/Math/Math.h"
#include "Engine/Platform/CPUInfo.h"
@@ -15,15 +13,43 @@ namespace
uint32 LastHostId = 0;
}
void NetworkPeer::Initialize(const NetworkConfig& config)
bool NetworkPeer::Initialize(const NetworkConfig& config)
{
Config = config;
if (NetworkDriver)
return true;
ASSERT(NetworkDriver == nullptr);
ASSERT(Config.NetworkDriverType != NetworkDriverType::Undefined);
ASSERT(Config.ConnectionsLimit > 0);
ASSERT(Config.MessageSize > 32); // TODO: Adjust this, not sure what the lowest limit should be.
ASSERT(Config.MessagePoolSize > 128);
Config = config;
PRAGMA_DISABLE_DEPRECATION_WARNINGS
if (Config.NetworkDriver == nullptr && Config.NetworkDriverType == NetworkDriverType::ENet)
Config.NetworkDriver = New<ENetDriver>();
PRAGMA_ENABLE_DEPRECATION_WARNINGS
if (Config.NetworkDriver == nullptr)
{
LOG(Error, "Missing NetworkDriver");
return true;
}
if (Config.ConnectionsLimit <= 0)
{
LOG(Error, "Invalid ConnectionsLimit");
return true;
}
if (Config.MessageSize <= 32) // TODO: Adjust this, not sure what the lowest limit should be.
{
LOG(Error, "Invalid MessageSize");
return true;
}
if (Config.MessagePoolSize <= 128)
{
LOG(Error, "Invalid MessagePoolSize");
return true;
}
NetworkDriver = ToInterface<INetworkDriver>(Config.NetworkDriver);
if (!NetworkDriver)
{
LOG(Error, "NetworkDriver doesn't implement INetworkDriver interface");
return true;
}
// TODO: Dynamic message pool allocation
// Setup messages
@@ -35,10 +61,14 @@ void NetworkPeer::Initialize(const NetworkConfig& config)
MessagePool.Push(messageId);
// Setup network driver
NetworkDriver = New<ENetDriver>();
NetworkDriver->Initialize(this, Config);
if (NetworkDriver->Initialize(this, Config))
{
LOG(Error, "Failed to initialize NetworkDriver");
return true;
}
LOG(Info, "NetworkManager initialized using driver = {0}", static_cast<int>(Config.NetworkDriverType));
LOG(Info, "NetworkManager initialized using driver = {0}", NetworkDriver->DriverName());
return false;
}
void NetworkPeer::Shutdown()
@@ -53,7 +83,7 @@ void NetworkPeer::Shutdown()
void NetworkPeer::CreateMessageBuffers()
{
ASSERT(MessageBuffer == nullptr);
const uint32 pageSize = Platform::GetCPUInfo().PageSize;
// Calculate total size in bytes
@@ -69,7 +99,7 @@ void NetworkPeer::CreateMessageBuffers()
void NetworkPeer::DisposeMessageBuffers()
{
ASSERT(MessageBuffer != nullptr);
Platform::FreePages(MessageBuffer);
MessageBuffer = nullptr;
}
@@ -117,7 +147,7 @@ void NetworkPeer::RecycleMessage(const NetworkMessage& message)
#ifdef BUILD_DEBUG
ASSERT(MessagePool.Contains(message.MessageId) == false);
#endif
// Return the message id
MessagePool.Push(message.MessageId);
}
@@ -136,7 +166,7 @@ void NetworkPeer::AbortSendMessage(const NetworkMessage& message)
bool NetworkPeer::EndSendMessage(const NetworkChannelType channelType, const NetworkMessage& message)
{
ASSERT(message.IsValid());
NetworkDriver->SendMessage(channelType, message);
RecycleMessage(message);
@@ -146,7 +176,7 @@ bool NetworkPeer::EndSendMessage(const NetworkChannelType channelType, const Net
bool NetworkPeer::EndSendMessage(const NetworkChannelType channelType, const NetworkMessage& message, const NetworkConnection& target)
{
ASSERT(message.IsValid());
NetworkDriver->SendMessage(channelType, message, target);
RecycleMessage(message);
@@ -156,7 +186,7 @@ bool NetworkPeer::EndSendMessage(const NetworkChannelType channelType, const Net
bool NetworkPeer::EndSendMessage(const NetworkChannelType channelType, const NetworkMessage& message, const Array<NetworkConnection>& targets)
{
ASSERT(message.IsValid());
NetworkDriver->SendMessage(channelType, message, targets);
RecycleMessage(message);
@@ -166,18 +196,28 @@ bool NetworkPeer::EndSendMessage(const NetworkChannelType channelType, const Net
NetworkPeer* NetworkPeer::CreatePeer(const NetworkConfig& config)
{
// Validate the address for listen/connect
NetworkEndPoint endPoint = {};
const bool isValidEndPoint = NetworkBase::CreateEndPoint(config.Address, String("7777"), NetworkIPVersion::IPv4, endPoint, false);
ASSERT(config.Address == String("any") || isValidEndPoint);
if (config.Address != TEXT("any"))
{
NetworkEndPoint endPoint;
if (Network::CreateEndPoint(config.Address, String::Empty, NetworkIPVersion::IPv4, endPoint, false))
{
LOG(Error, "Invalid end point.");
return nullptr;
}
}
// Alloc new host
Peers.Add(New<NetworkPeer>());
NetworkPeer* host = Peers.Last();
NetworkPeer* host = New<NetworkPeer>();
host->HostId = LastHostId++;
// Initialize the host
host->Initialize(config);
if (host->Initialize(config))
{
Delete(host);
return nullptr;
}
Peers.Add(host);
return host;
}
@@ -187,6 +227,6 @@ void NetworkPeer::ShutdownPeer(NetworkPeer* peer)
peer->Shutdown();
peer->HostId = -1;
Peers.Remove(peer);
Delete(peer);
}

View File

@@ -2,12 +2,11 @@
#pragma once
#include "Engine/Scripting/ScriptingType.h"
#include "Engine/Scripting/ScriptingObjectReference.h"
#include "Types.h"
#include "NetworkConfig.h"
#include "Engine/Core/Collections/Array.h"
#include "Engine/Scripting/ScriptingType.h"
#include "Engine/Scripting/ScriptingObjectReference.h"
/// <summary>
/// Low-level network peer class. Provides server-client communication functions, message processing and sending.
@@ -17,6 +16,7 @@ API_CLASS(sealed, NoSpawn, Namespace = "FlaxEngine.Networking") class FLAXENGINE
DECLARE_SCRIPTING_TYPE_NO_SPAWN(NetworkPeer);
friend class NetworkManager;
public:
int HostId = -1;
NetworkConfig Config;
INetworkDriver* NetworkDriver = nullptr;
@@ -25,22 +25,17 @@ public:
Array<uint32, HeapAllocation> MessagePool;
public:
/// <summary>
/// Initializes a new instance of the <see cref="NetworkPeer"/> class.
/// </summary>
NetworkPeer() : PersistentScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
NetworkPeer()
: PersistentScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
{
}
private:
void Initialize(const NetworkConfig& config);
void Shutdown();
private:
void CreateMessageBuffers();
void DisposeMessageBuffers();
public:
/// <summary>
/// Starts listening for incoming connections.
/// Once this is called, this peer becomes a server.
@@ -151,13 +146,12 @@ public:
API_FUNCTION()
bool EndSendMessage(NetworkChannelType channelType, const NetworkMessage& message, const Array<NetworkConnection, HeapAllocation>& targets);
public:
/// <summary>
/// Creates new peer using given configuration.
/// </summary>
/// <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.</remarks>
/// <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);
@@ -167,8 +161,9 @@ public:
/// <param name="peer">The peer to destroy.</param>
API_FUNCTION()
static void ShutdownPeer(NetworkPeer* peer);
public:
bool IsValid() const
{
return NetworkDriver != nullptr && HostId >= 0;
@@ -181,6 +176,7 @@ public:
}
public:
FORCE_INLINE bool operator==(const NetworkPeer& other) const
{
return HostId == other.HostId;
@@ -190,5 +186,11 @@ public:
{
return HostId != other.HostId;
}
};
private:
bool Initialize(const NetworkConfig& config);
void Shutdown();
void CreateMessageBuffers();
void DisposeMessageBuffers();
};

View File

@@ -2,19 +2,9 @@
#pragma once
#if PLATFORM_WINDOWS
#if PLATFORM_WINDOWS || PLATFORM_UWP || PLATFORM_XBOX_ONE || PLATFORM_XBOX_SCARLETT
#include "Win32/Win32ConditionVariable.h"
#elif PLATFORM_UWP
#include "Win32/Win32ConditionVariable.h"
#elif PLATFORM_LINUX
#include "Unix/UnixConditionVariable.h"
#elif PLATFORM_PS4
#include "Unix/UnixConditionVariable.h"
#elif PLATFORM_XBOX_ONE
#include "Win32/Win32ConditionVariable.h"
#elif PLATFORM_XBOX_SCARLETT
#include "Win32/Win32ConditionVariable.h"
#elif PLATFORM_ANDROID
#elif PLATFORM_LINUX || PLATFORM_ANDROID || PLATFORM_PS4 || PLATFORM_PS5
#include "Unix/UnixConditionVariable.h"
#elif PLATFORM_SWITCH
#include "Platforms/Switch/Engine/Platform/SwitchConditionVariable.h"

View File

@@ -22,7 +22,6 @@ void* UnixPlatform::Allocate(uint64 size, uint64 alignment)
{
uint32_t pad = sizeof(offset_t) + (alignment - 1);
void* p = malloc(size + pad);
if (p)
{
// Add the offset size to malloc's pointer
@@ -31,8 +30,10 @@ void* UnixPlatform::Allocate(uint64 size, uint64 alignment)
// Calculate the offset and store it behind aligned pointer
*((offset_t*)ptr - 1) = (offset_t)((uintptr_t)ptr - (uintptr_t)p);
}
#if COMPILE_WITH_PROFILER
OnMemoryAlloc(ptr, size);
#endif
}
return ptr;
}
@@ -40,11 +41,14 @@ void UnixPlatform::Free(void* ptr)
{
if (ptr)
{
#if COMPILE_WITH_PROFILER
OnMemoryFree(ptr);
#endif
// Walk backwards from the passed-in pointer to get the pointer offset
offset_t offset = *((offset_t*)ptr - 1);
// Get original pointer
void* p = (void *)((uint8_t *)ptr - offset);
void* p = (void*)((uint8_t*)ptr - offset);
// Free memory
free(p);

View File

@@ -18,6 +18,8 @@
#include "Android/AndroidWindow.h"
#elif PLATFORM_SWITCH
#include "Platforms/Switch/Engine/Platform/SwitchWindow.h"
#elif PLATFORM_PS5
#include "Platforms/PS5/Engine/Platform/PS5Window.h"
#else
#error Missing Window implementation!
#endif

View File

@@ -96,7 +96,7 @@ bool FeatureData::Init()
if (c == '@')
break;
}
const Char* end = &contents[i];
const Char* end = contents.Get() + i;
// Set input
Inputs[inIndex].Set(start, (int32)(end - start));