Merge branch 'master' into Visject-ImprovedNodeSearching
This commit is contained in:
Binary file not shown.
Binary file not shown.
+2
-1
@@ -3,7 +3,8 @@
|
||||
"Version": {
|
||||
"Major": 1,
|
||||
"Minor": 7,
|
||||
"Build": 6402
|
||||
"Revision": 0,
|
||||
"Build": 6404
|
||||
},
|
||||
"Company": "Flax",
|
||||
"Copyright": "Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.",
|
||||
|
||||
@@ -154,7 +154,8 @@ bool ProjectInfo::LoadProject(const String& projectPath)
|
||||
Version = ::Version(
|
||||
JsonTools::GetInt(version, "Major", 0),
|
||||
JsonTools::GetInt(version, "Minor", 0),
|
||||
JsonTools::GetInt(version, "Build", 0));
|
||||
JsonTools::GetInt(version, "Build", -1),
|
||||
JsonTools::GetInt(version, "Revision", -1));
|
||||
}
|
||||
}
|
||||
if (Version.Revision() == 0)
|
||||
|
||||
@@ -23,17 +23,11 @@ namespace FlaxEditor
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
writer.WriteNull();
|
||||
}
|
||||
else if (value is Version)
|
||||
{
|
||||
writer.WriteValue(value.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonSerializationException("Expected Version object value");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -47,65 +41,60 @@ namespace FlaxEditor
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.Null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
|
||||
if (reader.TokenType == JsonToken.StartObject)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.StartObject)
|
||||
try
|
||||
{
|
||||
try
|
||||
reader.Read();
|
||||
var values = new Dictionary<string, int>();
|
||||
while (reader.TokenType == JsonToken.PropertyName)
|
||||
{
|
||||
var key = reader.Value as string;
|
||||
reader.Read();
|
||||
Dictionary<string, int> values = new Dictionary<string, int>();
|
||||
while (reader.TokenType == JsonToken.PropertyName)
|
||||
{
|
||||
var key = reader.Value as string;
|
||||
reader.Read();
|
||||
var val = (long)reader.Value;
|
||||
reader.Read();
|
||||
values.Add(key, (int)val);
|
||||
}
|
||||
var val = (long)reader.Value;
|
||||
reader.Read();
|
||||
values.Add(key, (int)val);
|
||||
}
|
||||
|
||||
int major = 0, minor = 0, build = 0;
|
||||
values.TryGetValue("Major", out major);
|
||||
values.TryGetValue("Minor", out minor);
|
||||
values.TryGetValue("Build", out build);
|
||||
values.TryGetValue("Major", out var major);
|
||||
values.TryGetValue("Minor", out var minor);
|
||||
if (!values.TryGetValue("Build", out var build))
|
||||
build = -1;
|
||||
if (!values.TryGetValue("Revision", out var revision))
|
||||
revision = -1;
|
||||
|
||||
Version v = new Version(major, minor, build);
|
||||
return v;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception(String.Format("Error parsing version string: {0}", reader.Value), ex);
|
||||
}
|
||||
if (build <= 0)
|
||||
return new Version(major, minor);
|
||||
if (revision <= 0)
|
||||
return new Version(major, minor, build);
|
||||
return new Version(major, minor, build, revision);
|
||||
}
|
||||
else if (reader.TokenType == JsonToken.String)
|
||||
catch (Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
Version v = new Version((string)reader.Value!);
|
||||
return v;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception(String.Format("Error parsing version string: {0}", reader.Value), ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(String.Format("Unexpected token or value when parsing version. Token: {0}, Value: {1}", reader.TokenType, reader.Value));
|
||||
throw new Exception(String.Format("Error parsing version string: {0}", reader.Value), ex);
|
||||
}
|
||||
}
|
||||
if (reader.TokenType == JsonToken.String)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new Version((string)reader.Value!);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception(String.Format("Error parsing version string: {0}", reader.Value), ex);
|
||||
}
|
||||
}
|
||||
throw new Exception(String.Format("Unexpected token or value when parsing version. Token: {0}, Value: {1}", reader.TokenType, reader.Value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this instance can convert the specified object type.
|
||||
/// </summary>
|
||||
/// <param name="objectType">Type of the object.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
/// <returns><c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.</returns>
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return objectType == typeof(Version);
|
||||
|
||||
@@ -7,15 +7,15 @@ Version::Version(int32 major, int32 minor, int32 build, int32 revision)
|
||||
{
|
||||
_major = Math::Max(major, 0);
|
||||
_minor = Math::Max(minor, 0);
|
||||
_build = Math::Max(build, 0);
|
||||
_revision = Math::Max(revision, 0);
|
||||
_build = Math::Max(build, -1);
|
||||
_revision = Math::Max(revision, -1);
|
||||
}
|
||||
|
||||
Version::Version(int32 major, int32 minor, int32 build)
|
||||
{
|
||||
_major = Math::Max(major, 0);
|
||||
_minor = Math::Max(minor, 0);
|
||||
_build = Math::Max(build, 0);
|
||||
_build = Math::Max(build, -1);
|
||||
_revision = -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1302,7 +1302,8 @@ namespace FlaxEngine.Interop
|
||||
#if !USE_AOT
|
||||
internal bool TryGetDelegate(out Invoker.MarshalAndInvokeDelegate outDeleg, out object outDelegInvoke)
|
||||
{
|
||||
if (invokeDelegate == null)
|
||||
// Skip using in-built delegate for value types (eg. Transform) to properly handle instance value passing to method
|
||||
if (invokeDelegate == null && !method.DeclaringType.IsValueType)
|
||||
{
|
||||
List<Type> methodTypes = new List<Type>();
|
||||
if (!method.IsStatic)
|
||||
|
||||
@@ -313,6 +313,8 @@ bool GPUDevice::Init()
|
||||
|
||||
_res->TasksManager.SetExecutor(CreateTasksExecutor());
|
||||
LOG(Info, "Total graphics memory: {0}", Utilities::BytesToText(TotalGraphicsMemory));
|
||||
if (!Limits.HasCompute)
|
||||
LOG(Warning, "Compute Shaders are not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,11 @@ bool GPUShader::Create(MemoryReadStream& stream)
|
||||
GPUShaderProgramInitializer initializer;
|
||||
#if !BUILD_RELEASE
|
||||
initializer.Owner = this;
|
||||
const StringView name = GetName();
|
||||
#else
|
||||
const StringView name;
|
||||
#endif
|
||||
const bool hasCompute = GPUDevice::Instance->Limits.HasCompute;
|
||||
for (int32 i = 0; i < shadersCount; i++)
|
||||
{
|
||||
const ShaderStage type = static_cast<ShaderStage>(stream.ReadByte());
|
||||
@@ -117,10 +121,15 @@ bool GPUShader::Create(MemoryReadStream& stream)
|
||||
stream.ReadBytes(&initializer.Bindings, sizeof(ShaderBindings));
|
||||
|
||||
// Create shader program
|
||||
if (type == ShaderStage::Compute && !hasCompute)
|
||||
{
|
||||
LOG(Warning, "Failed to create {} Shader program '{}' ({}).", ::ToString(type), String(initializer.Name), name);
|
||||
continue;
|
||||
}
|
||||
GPUShaderProgram* shader = CreateGPUShaderProgram(type, initializer, cache, cacheSize, stream);
|
||||
if (shader == nullptr)
|
||||
{
|
||||
LOG(Error, "Failed to create {} Shader program '{}'.", ::ToString(type), String(initializer.Name));
|
||||
LOG(Error, "Failed to create {} Shader program '{}' ({}).", ::ToString(type), String(initializer.Name), name);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -122,6 +122,19 @@ public:
|
||||
/// </summary>
|
||||
class GPUShaderProgramVS : public GPUShaderProgram
|
||||
{
|
||||
public:
|
||||
// Input element run-time data (see VertexShaderMeta::InputElement for compile-time data)
|
||||
PACK_STRUCT(struct InputElement
|
||||
{
|
||||
byte Type; // VertexShaderMeta::InputType
|
||||
byte Index;
|
||||
byte Format; // PixelFormat
|
||||
byte InputSlot;
|
||||
uint32 AlignedByteOffset; // Fixed value or INPUT_LAYOUT_ELEMENT_ALIGN if auto
|
||||
byte InputSlotClass; // INPUT_LAYOUT_ELEMENT_PER_VERTEX_DATA or INPUT_LAYOUT_ELEMENT_PER_INSTANCE_DATA
|
||||
uint32 InstanceDataStepRate; // 0 if per-vertex
|
||||
});
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Gets input layout description handle (platform dependent).
|
||||
|
||||
@@ -15,32 +15,21 @@ GPUShaderProgram* GPUShaderDX11::CreateGPUShaderProgram(ShaderStage type, const
|
||||
{
|
||||
case ShaderStage::Vertex:
|
||||
{
|
||||
D3D11_INPUT_ELEMENT_DESC inputLayoutDesc[VERTEX_SHADER_MAX_INPUT_ELEMENTS];
|
||||
|
||||
// Temporary variables
|
||||
byte Type, Format, Index, InputSlot, InputSlotClass;
|
||||
uint32 AlignedByteOffset, InstanceDataStepRate;
|
||||
|
||||
// Load Input Layout (it may be empty)
|
||||
// Load Input Layout
|
||||
byte inputLayoutSize;
|
||||
stream.ReadByte(&inputLayoutSize);
|
||||
ASSERT(inputLayoutSize <= VERTEX_SHADER_MAX_INPUT_ELEMENTS);
|
||||
D3D11_INPUT_ELEMENT_DESC inputLayoutDesc[VERTEX_SHADER_MAX_INPUT_ELEMENTS];
|
||||
for (int32 a = 0; a < inputLayoutSize; a++)
|
||||
{
|
||||
// Read description
|
||||
// TODO: maybe use struct and load at once?
|
||||
stream.ReadByte(&Type);
|
||||
stream.ReadByte(&Index);
|
||||
stream.ReadByte(&Format);
|
||||
stream.ReadByte(&InputSlot);
|
||||
stream.ReadUint32(&AlignedByteOffset);
|
||||
stream.ReadByte(&InputSlotClass);
|
||||
stream.ReadUint32(&InstanceDataStepRate);
|
||||
GPUShaderProgramVS::InputElement inputElement;
|
||||
stream.Read(inputElement);
|
||||
|
||||
// Get semantic name
|
||||
const char* semanticName = nullptr;
|
||||
// TODO: maybe use enum+mapping ?
|
||||
switch (Type)
|
||||
switch (inputElement.Type)
|
||||
{
|
||||
case 1:
|
||||
semanticName = "POSITION";
|
||||
@@ -70,7 +59,7 @@ GPUShaderProgram* GPUShaderDX11::CreateGPUShaderProgram(ShaderStage type, const
|
||||
semanticName = "BLENDWEIGHT";
|
||||
break;
|
||||
default:
|
||||
LOG(Fatal, "Invalid vertex shader element semantic type: {0}", Type);
|
||||
LOG(Fatal, "Invalid vertex shader element semantic type: {0}", inputElement.Type);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -78,12 +67,12 @@ GPUShaderProgram* GPUShaderDX11::CreateGPUShaderProgram(ShaderStage type, const
|
||||
inputLayoutDesc[a] =
|
||||
{
|
||||
semanticName,
|
||||
static_cast<UINT>(Index),
|
||||
static_cast<DXGI_FORMAT>(Format),
|
||||
static_cast<UINT>(InputSlot),
|
||||
static_cast<UINT>(AlignedByteOffset),
|
||||
static_cast<D3D11_INPUT_CLASSIFICATION>(InputSlotClass),
|
||||
static_cast<UINT>(InstanceDataStepRate)
|
||||
static_cast<UINT>(inputElement.Index),
|
||||
static_cast<DXGI_FORMAT>(inputElement.Format),
|
||||
static_cast<UINT>(inputElement.InputSlot),
|
||||
static_cast<UINT>(inputElement.AlignedByteOffset),
|
||||
static_cast<D3D11_INPUT_CLASSIFICATION>(inputElement.InputSlotClass),
|
||||
static_cast<UINT>(inputElement.InstanceDataStepRate)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -20,32 +20,21 @@ GPUShaderProgram* GPUShaderDX12::CreateGPUShaderProgram(ShaderStage type, const
|
||||
{
|
||||
case ShaderStage::Vertex:
|
||||
{
|
||||
D3D12_INPUT_ELEMENT_DESC inputLayout[VERTEX_SHADER_MAX_INPUT_ELEMENTS];
|
||||
|
||||
// Temporary variables
|
||||
byte Type, Format, Index, InputSlot, InputSlotClass;
|
||||
uint32 AlignedByteOffset, InstanceDataStepRate;
|
||||
|
||||
// Load Input Layout (it may be empty)
|
||||
byte inputLayoutSize;
|
||||
stream.ReadByte(&inputLayoutSize);
|
||||
ASSERT(inputLayoutSize <= VERTEX_SHADER_MAX_INPUT_ELEMENTS);
|
||||
D3D12_INPUT_ELEMENT_DESC inputLayout[VERTEX_SHADER_MAX_INPUT_ELEMENTS];
|
||||
for (int32 a = 0; a < inputLayoutSize; a++)
|
||||
{
|
||||
// Read description
|
||||
// TODO: maybe use struct and load at once?
|
||||
stream.ReadByte(&Type);
|
||||
stream.ReadByte(&Index);
|
||||
stream.ReadByte(&Format);
|
||||
stream.ReadByte(&InputSlot);
|
||||
stream.ReadUint32(&AlignedByteOffset);
|
||||
stream.ReadByte(&InputSlotClass);
|
||||
stream.ReadUint32(&InstanceDataStepRate);
|
||||
GPUShaderProgramVS::InputElement inputElement;
|
||||
stream.Read(inputElement);
|
||||
|
||||
// Get semantic name
|
||||
const char* semanticName = nullptr;
|
||||
// TODO: maybe use enum+mapping ?
|
||||
switch (Type)
|
||||
switch (inputElement.Type)
|
||||
{
|
||||
case 1:
|
||||
semanticName = "POSITION";
|
||||
@@ -75,7 +64,7 @@ GPUShaderProgram* GPUShaderDX12::CreateGPUShaderProgram(ShaderStage type, const
|
||||
semanticName = "BLENDWEIGHT";
|
||||
break;
|
||||
default:
|
||||
LOG(Fatal, "Invalid vertex shader element semantic type: {0}", Type);
|
||||
LOG(Fatal, "Invalid vertex shader element semantic type: {0}", inputElement.Type);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -83,12 +72,12 @@ GPUShaderProgram* GPUShaderDX12::CreateGPUShaderProgram(ShaderStage type, const
|
||||
inputLayout[a] =
|
||||
{
|
||||
semanticName,
|
||||
static_cast<UINT>(Index),
|
||||
static_cast<DXGI_FORMAT>(Format),
|
||||
static_cast<UINT>(InputSlot),
|
||||
static_cast<UINT>(AlignedByteOffset),
|
||||
static_cast<D3D12_INPUT_CLASSIFICATION>(InputSlotClass),
|
||||
static_cast<UINT>(InstanceDataStepRate)
|
||||
static_cast<UINT>(inputElement.Index),
|
||||
static_cast<DXGI_FORMAT>(inputElement.Format),
|
||||
static_cast<UINT>(inputElement.InputSlot),
|
||||
static_cast<UINT>(inputElement.AlignedByteOffset),
|
||||
static_cast<D3D12_INPUT_CLASSIFICATION>(inputElement.InputSlotClass),
|
||||
static_cast<UINT>(inputElement.InstanceDataStepRate)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
#include "Engine/Graphics/PixelFormatExtensions.h"
|
||||
|
||||
#if PLATFORM_DESKTOP
|
||||
#define VULKAN_UNIFORM_RING_BUFFER_SIZE 24 * 1024 * 1024
|
||||
#define VULKAN_UNIFORM_RING_BUFFER_SIZE (24 * 1024 * 1024)
|
||||
#else
|
||||
#define VULKAN_UNIFORM_RING_BUFFER_SIZE 8 * 1024 * 1024
|
||||
#define VULKAN_UNIFORM_RING_BUFFER_SIZE (8 * 1024 * 1024)
|
||||
#endif
|
||||
|
||||
UniformBufferUploaderVulkan::UniformBufferUploaderVulkan(GPUDeviceVulkan* device)
|
||||
@@ -153,10 +153,6 @@ GPUShaderProgram* GPUShaderVulkan::CreateGPUShaderProgram(ShaderStage type, cons
|
||||
vertexBindingDescriptions[i].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
}
|
||||
|
||||
// Temporary variables
|
||||
byte Type, Format, Index, InputSlot, InputSlotClass;
|
||||
uint32 AlignedByteOffset, InstanceDataStepRate;
|
||||
|
||||
// Load Input Layout (it may be empty)
|
||||
byte inputLayoutSize;
|
||||
stream.ReadByte(&inputLayoutSize);
|
||||
@@ -167,32 +163,26 @@ GPUShaderProgram* GPUShaderVulkan::CreateGPUShaderProgram(ShaderStage type, cons
|
||||
for (int32 a = 0; a < inputLayoutSize; a++)
|
||||
{
|
||||
// Read description
|
||||
// TODO: maybe use struct and load at once?
|
||||
stream.ReadByte(&Type);
|
||||
stream.ReadByte(&Index);
|
||||
stream.ReadByte(&Format);
|
||||
stream.ReadByte(&InputSlot);
|
||||
stream.ReadUint32(&AlignedByteOffset);
|
||||
stream.ReadByte(&InputSlotClass);
|
||||
stream.ReadUint32(&InstanceDataStepRate);
|
||||
GPUShaderProgramVS::InputElement inputElement;
|
||||
stream.Read(inputElement);
|
||||
|
||||
const auto size = PixelFormatExtensions::SizeInBytes((PixelFormat)Format);
|
||||
if (AlignedByteOffset != INPUT_LAYOUT_ELEMENT_ALIGN)
|
||||
offset = AlignedByteOffset;
|
||||
const auto size = PixelFormatExtensions::SizeInBytes((PixelFormat)inputElement.Format);
|
||||
if (inputElement.AlignedByteOffset != INPUT_LAYOUT_ELEMENT_ALIGN)
|
||||
offset = inputElement.AlignedByteOffset;
|
||||
|
||||
auto& vertexBindingDescription = vertexBindingDescriptions[InputSlot];
|
||||
vertexBindingDescription.binding = InputSlot;
|
||||
auto& vertexBindingDescription = vertexBindingDescriptions[inputElement.InputSlot];
|
||||
vertexBindingDescription.binding = inputElement.InputSlot;
|
||||
vertexBindingDescription.stride = Math::Max(vertexBindingDescription.stride, (uint32_t)(offset + size));
|
||||
vertexBindingDescription.inputRate = InputSlotClass == INPUT_LAYOUT_ELEMENT_PER_VERTEX_DATA ? VK_VERTEX_INPUT_RATE_VERTEX : VK_VERTEX_INPUT_RATE_INSTANCE;
|
||||
ASSERT(InstanceDataStepRate == 0 || InstanceDataStepRate == 1);
|
||||
vertexBindingDescription.inputRate = inputElement.InputSlotClass == INPUT_LAYOUT_ELEMENT_PER_VERTEX_DATA ? VK_VERTEX_INPUT_RATE_VERTEX : VK_VERTEX_INPUT_RATE_INSTANCE;
|
||||
ASSERT(inputElement.InstanceDataStepRate == 0 || inputElement.InstanceDataStepRate == 1);
|
||||
|
||||
auto& vertexAttributeDescription = vertexAttributeDescriptions[a];
|
||||
vertexAttributeDescription.location = a;
|
||||
vertexAttributeDescription.binding = InputSlot;
|
||||
vertexAttributeDescription.format = RenderToolsVulkan::ToVulkanFormat((PixelFormat)Format);
|
||||
vertexAttributeDescription.binding = inputElement.InputSlot;
|
||||
vertexAttributeDescription.format = RenderToolsVulkan::ToVulkanFormat((PixelFormat)inputElement.Format);
|
||||
vertexAttributeDescription.offset = offset;
|
||||
|
||||
bindingsCount = Math::Max(bindingsCount, (uint32)InputSlot + 1);
|
||||
bindingsCount = Math::Max(bindingsCount, (uint32)inputElement.InputSlot + 1);
|
||||
offset += size;
|
||||
}
|
||||
|
||||
|
||||
@@ -1334,7 +1334,8 @@ void ParticlesSystem::Job(int32 index)
|
||||
auto emitter = particleSystem->Emitters[track.AsEmitter.Index].Get();
|
||||
auto& data = instance.Emitters[track.AsEmitter.Index];
|
||||
ASSERT(emitter && emitter->IsLoaded());
|
||||
ASSERT(emitter->Capacity != 0 && emitter->Graph.Layout.Size != 0);
|
||||
if (emitter->Capacity == 0 || emitter->Graph.Layout.Size == 0)
|
||||
continue;
|
||||
PROFILE_CPU_ASSET(emitter);
|
||||
|
||||
// Calculate new time position
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "PhysicsColliderActor.h"
|
||||
#include "Engine/Scripting/Script.h"
|
||||
#include "RigidBody.h"
|
||||
|
||||
PhysicsColliderActor::PhysicsColliderActor(const SpawnParams& params)
|
||||
|
||||
@@ -1270,7 +1270,11 @@ bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Sp
|
||||
|
||||
// Invoke the method
|
||||
MObject* exception = nullptr;
|
||||
#if USE_NETCORE // NetCore uses the same path for both virtual and non-virtual calls
|
||||
MObject* resultObject = mMethod->Invoke(mInstance, params, &exception);
|
||||
#else
|
||||
MObject* resultObject = withInterfaces ? mMethod->InvokeVirtual((MObject*)mInstance, params, &exception) : mMethod->Invoke(mInstance, params, &exception);
|
||||
#endif
|
||||
if (exception)
|
||||
{
|
||||
MException ex(exception);
|
||||
|
||||
@@ -460,16 +460,15 @@ bool ShaderCompiler::WriteCustomDataVS(ShaderCompilationContext* context, Shader
|
||||
auto& element = layout[a];
|
||||
if (!layoutVisible[a])
|
||||
continue;
|
||||
|
||||
// TODO: serialize whole struct?
|
||||
|
||||
output->WriteByte(static_cast<byte>(element.Type));
|
||||
output->WriteByte(element.Index);
|
||||
output->WriteByte(static_cast<byte>(element.Format));
|
||||
output->WriteByte(element.InputSlot);
|
||||
output->WriteUint32(element.AlignedByteOffset);
|
||||
output->WriteByte(element.InputSlotClass);
|
||||
output->WriteUint32(element.InstanceDataStepRate);
|
||||
GPUShaderProgramVS::InputElement data;
|
||||
data.Type = static_cast<byte>(element.Type);
|
||||
data.Index = element.Index;
|
||||
data.Format = static_cast<byte>(element.Format);
|
||||
data.InputSlot = element.InputSlot;
|
||||
data.AlignedByteOffset = element.AlignedByteOffset;
|
||||
data.InputSlotClass = element.InputSlotClass;
|
||||
data.InstanceDataStepRate = element.InstanceDataStepRate;
|
||||
output->Write(data);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -222,7 +222,7 @@ ${PBXResourcesGroup}
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = ${HeaderSearchPaths};
|
||||
HEADER_SEARCH_PATHS = "${HeaderSearchPaths}";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
@@ -275,7 +275,7 @@ ${PBXResourcesGroup}
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = ${HeaderSearchPaths};
|
||||
HEADER_SEARCH_PATHS = "${HeaderSearchPaths}";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
|
||||
@@ -3135,14 +3135,17 @@ namespace Flax.Build.Bindings
|
||||
contents.AppendLine("#pragma once");
|
||||
contents.AppendLine();
|
||||
contents.AppendLine($"#define {binaryModuleNameUpper}_NAME \"{binaryModuleName}\"");
|
||||
if (version.Build == -1)
|
||||
if (version.Build <= 0)
|
||||
contents.AppendLine($"#define {binaryModuleNameUpper}_VERSION Version({version.Major}, {version.Minor})");
|
||||
else
|
||||
else if (version.Revision <= 0)
|
||||
contents.AppendLine($"#define {binaryModuleNameUpper}_VERSION Version({version.Major}, {version.Minor}, {version.Build})");
|
||||
else
|
||||
contents.AppendLine($"#define {binaryModuleNameUpper}_VERSION Version({version.Major}, {version.Minor}, {version.Build}, {version.Revision})");
|
||||
contents.AppendLine($"#define {binaryModuleNameUpper}_VERSION_TEXT \"{version}\"");
|
||||
contents.AppendLine($"#define {binaryModuleNameUpper}_VERSION_MAJOR {version.Major}");
|
||||
contents.AppendLine($"#define {binaryModuleNameUpper}_VERSION_MINOR {version.Minor}");
|
||||
contents.AppendLine($"#define {binaryModuleNameUpper}_VERSION_BUILD {version.Build}");
|
||||
contents.AppendLine($"#define {binaryModuleNameUpper}_VERSION_REVISION {version.Revision}");
|
||||
contents.AppendLine($"#define {binaryModuleNameUpper}_COMPANY \"{project.Company}\"");
|
||||
contents.AppendLine($"#define {binaryModuleNameUpper}_COPYRIGHT \"{project.Copyright}\"");
|
||||
contents.AppendLine();
|
||||
|
||||
@@ -14,9 +14,9 @@ namespace Flax.Build
|
||||
/// <summary>
|
||||
/// Writes the JSON representation of the object.
|
||||
/// </summary>
|
||||
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
|
||||
/// <param name="writer">The <see cref="Utf8JsonWriter"/> to write to.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="serializer">The calling serializer.</param>
|
||||
/// <param name="options">The calling serializer.</param>
|
||||
public override void Write(Utf8JsonWriter writer, Version value, JsonSerializerOptions options)
|
||||
{
|
||||
writer.WriteStringValue(value.ToString());
|
||||
@@ -25,73 +25,68 @@ namespace Flax.Build
|
||||
/// <summary>
|
||||
/// Reads the JSON representation of the object.
|
||||
/// </summary>
|
||||
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
|
||||
/// <param name="objectType">Type of the object.</param>
|
||||
/// <param name="existingValue">The existing property value of the JSON that is being converted.</param>
|
||||
/// <param name="serializer">The calling serializer.</param>
|
||||
/// <param name="reader">The <see cref="Utf8JsonReader"/> to read from.</param>
|
||||
/// <param name="typeToConvert">Type of the object.</param>
|
||||
/// <param name="options">The serializer options.</param>
|
||||
/// <returns>The object value.</returns>
|
||||
public override Version? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
if (reader.TokenType == JsonTokenType.Null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
|
||||
if (reader.TokenType == JsonTokenType.StartObject)
|
||||
{
|
||||
if (reader.TokenType == JsonTokenType.StartObject)
|
||||
try
|
||||
{
|
||||
try
|
||||
reader.Read();
|
||||
var values = new Dictionary<string, int>();
|
||||
while (reader.TokenType == JsonTokenType.PropertyName)
|
||||
{
|
||||
var key = reader.GetString();
|
||||
reader.Read();
|
||||
Dictionary<string, int> values = new Dictionary<string, int>();
|
||||
while (reader.TokenType == JsonTokenType.PropertyName)
|
||||
{
|
||||
var key = reader.GetString();
|
||||
reader.Read();
|
||||
var val = reader.GetInt32();
|
||||
reader.Read();
|
||||
values.Add(key, val);
|
||||
}
|
||||
var val = reader.GetInt32();
|
||||
reader.Read();
|
||||
values.Add(key, val);
|
||||
}
|
||||
|
||||
int major = 0, minor = 0, build = 0;
|
||||
values.TryGetValue("Major", out major);
|
||||
values.TryGetValue("Minor", out minor);
|
||||
values.TryGetValue("Build", out build);
|
||||
values.TryGetValue("Major", out var major);
|
||||
values.TryGetValue("Minor", out var minor);
|
||||
if (!values.TryGetValue("Build", out var build))
|
||||
build = -1;
|
||||
if (!values.TryGetValue("Revision", out var revision))
|
||||
revision = -1;
|
||||
|
||||
Version v = new Version(major, minor, build);
|
||||
return v;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception(String.Format("Error parsing version string: {0}", reader.GetString()), ex);
|
||||
}
|
||||
if (build <= 0)
|
||||
return new Version(major, minor);
|
||||
if (revision <= 0)
|
||||
return new Version(major, minor, build);
|
||||
return new Version(major, minor, build, revision);
|
||||
}
|
||||
else if (reader.TokenType == JsonTokenType.String)
|
||||
catch (Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
Version v = new Version((string)reader.GetString()!);
|
||||
return v;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception(String.Format("Error parsing version string: {0}", reader.GetString()), ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(String.Format("Unexpected token or value when parsing version. Token: {0}, Value: {1}", reader.TokenType, reader.GetString()));
|
||||
throw new Exception(string.Format("Error parsing version string: {0}", reader.GetString()), ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (reader.TokenType == JsonTokenType.String)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new Version((string)reader.GetString()!);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception(string.Format("Error parsing version string: {0}", reader.GetString()), ex);
|
||||
}
|
||||
}
|
||||
throw new Exception(string.Format("Unexpected token or value when parsing version. Token: {0}, Value: {1}", reader.TokenType, reader.GetString()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this instance can convert the specified object type.
|
||||
/// </summary>
|
||||
/// <param name="objectType">Type of the object.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
/// <returns><c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.</returns>
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return objectType == typeof(Version);
|
||||
@@ -318,7 +313,7 @@ namespace Flax.Build
|
||||
Log.Verbose("Loading project file from \"" + path + "\"...");
|
||||
var contents = File.ReadAllText(path);
|
||||
var project = JsonSerializer.Deserialize<ProjectInfo>(contents.AsSpan(),
|
||||
new JsonSerializerOptions() { Converters = { new FlaxVersionConverter() }, IncludeFields = true, TypeInfoResolver = ProjectInfoSourceGenerationContext.Default });
|
||||
new JsonSerializerOptions() { Converters = { new FlaxVersionConverter() }, IncludeFields = true, TypeInfoResolver = ProjectInfoSourceGenerationContext.Default });
|
||||
project.ProjectPath = path;
|
||||
project.ProjectFolderPath = Path.GetDirectoryName(path);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user