Merge branch 'master' into ImprovementSlider
This commit is contained in:
+1
-1
@@ -4,7 +4,7 @@
|
||||
"Major": 1,
|
||||
"Minor": 12,
|
||||
"Revision": 0,
|
||||
"Build": 6913
|
||||
"Build": 6914
|
||||
},
|
||||
"Company": "Flax",
|
||||
"Copyright": "Copyright (c) 2012-2026 Wojciech Figat. All rights reserved.",
|
||||
|
||||
@@ -191,7 +191,7 @@ bool WebPlatformTools::OnPostProcess(CookingData& data)
|
||||
FileSystem::GetChildDirectories(pythons, emscriptenSdk / TEXT("/python"));
|
||||
if (pythons.HasItems())
|
||||
{
|
||||
procSettings.Arguments = procSettings.FileName + TEXT(".py ") + procSettings.Arguments;
|
||||
procSettings.Arguments = String::Format(TEXT("\"{}.py\" {}"), procSettings.FileName, procSettings.Arguments);
|
||||
#if PLATFORM_WINDOWS
|
||||
procSettings.FileName = pythons[0] / TEXT("/python.exe");
|
||||
#else
|
||||
|
||||
@@ -8,6 +8,7 @@ using FlaxEditor.Gizmo;
|
||||
using FlaxEditor.GUI.Tabs;
|
||||
using FlaxEditor.Modules;
|
||||
using FlaxEditor.SceneGraph;
|
||||
using FlaxEditor.Utilities;
|
||||
using FlaxEditor.Viewport.Modes;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
@@ -307,7 +308,7 @@ namespace FlaxEditor.Tools
|
||||
public VertexPaintingGizmo Gizmo;
|
||||
|
||||
public VertexColorsPreviewMode PreviewMode = VertexColorsPreviewMode.RGB;
|
||||
public float PreviewVertexSize = 6.0f;
|
||||
public float PreviewVertexSize = 4.0f;
|
||||
public float BrushSize = 100.0f;
|
||||
public float BrushStrength = 1.0f;
|
||||
public float BrushFalloff = 1.0f;
|
||||
@@ -402,7 +403,7 @@ namespace FlaxEditor.Tools
|
||||
if (meshDatas == null)
|
||||
throw new Exception("Missing mesh data of the model to paint.");
|
||||
var instanceTransform = _selectedModel.Transform;
|
||||
var brushSphere = new BoundingSphere(_hitLocation, _gizmoMode.BrushSize);
|
||||
var brushSphere = new BoundingSphere(_hitLocation, _gizmoMode.BrushSize * 0.5f);
|
||||
if (_paintUpdateCount == 0 && !_selectedModel.HasVertexColors)
|
||||
{
|
||||
// Initialize the instance vertex colors with originals from the asset
|
||||
@@ -509,6 +510,13 @@ namespace FlaxEditor.Tools
|
||||
return;
|
||||
}
|
||||
|
||||
// Increase or decrease brush size with scroll
|
||||
if (Input.GetKey(KeyboardKeys.Shift) && !Input.GetMouseButton(MouseButton.Right))
|
||||
{
|
||||
_gizmoMode.BrushSize += dt * _gizmoMode.BrushSize * Input.Mouse.ScrollDelta * 5f;
|
||||
_gizmoMode.BrushSize = Mathf.Clamp(_gizmoMode.BrushSize, 0.0001f, 100000.0f);
|
||||
}
|
||||
|
||||
// Perform detailed tracing to find cursor location for the brush
|
||||
var ray = Owner.MouseRay;
|
||||
var view = new Ray(Owner.ViewPosition, Owner.ViewDirection);
|
||||
@@ -570,7 +578,7 @@ namespace FlaxEditor.Tools
|
||||
}
|
||||
if (_brushModel && _brushMaterial)
|
||||
{
|
||||
_brushMaterial.SetParameterValue("Color", new Color(1.0f, 0.85f, 0.0f)); // TODO: expose to editor options
|
||||
_brushMaterial.SetParameterValue("Color", new Color(1.0f, 0.85f, 0.0f));
|
||||
_brushMaterial.SetParameterValue("DepthBuffer", Owner.RenderTask.Buffers.DepthBuffer);
|
||||
Quaternion rotation = RootNode.RaycastNormalRotation(ref _hitNormal);
|
||||
Matrix transform = Matrix.Scaling(_gizmoMode.BrushSize * 0.01f) * Matrix.RotationQuaternion(rotation) * Matrix.Translation(_hitLocation - viewOrigin);
|
||||
@@ -586,8 +594,10 @@ namespace FlaxEditor.Tools
|
||||
_verticesPreviewMaterial = FlaxEngine.Content.LoadAsyncInternal<MaterialBase>(EditorAssets.WiresDebugMaterial);
|
||||
}
|
||||
var instanceTransform = _selectedModel.Transform;
|
||||
var modelScaleMatrix = Matrix.Scaling(_gizmoMode.PreviewVertexSize * 0.01f);
|
||||
var brushSphere = new BoundingSphere(_hitLocation, _gizmoMode.BrushSize);
|
||||
var distanceScale = (float)Vector3.Distance(instanceTransform.Translation, renderContext.View.Position) / (10.0f * Units.Meters2Units);
|
||||
var vertexScale = Mathf.Lerp(0.005f, 0.01f, Mathf.Saturate(distanceScale));
|
||||
var modelScaleMatrix = Matrix.Scaling(_gizmoMode.PreviewVertexSize * vertexScale);
|
||||
var brushSphere = new BoundingSphere(_hitLocation, _gizmoMode.BrushSize * 0.5f);
|
||||
var lodIndex = _gizmoMode.ModelLOD == -1 ? RenderTools.ComputeModelLOD(_selectedModel.Model, ref renderContext.View.Position, (float)_selectedModel.Sphere.Radius, ref renderContext) : _gizmoMode.ModelLOD;
|
||||
lodIndex = Mathf.Clamp(lodIndex, 0, meshDatas.Length - 1);
|
||||
var lodData = meshDatas[lodIndex];
|
||||
|
||||
@@ -98,10 +98,10 @@ namespace FlaxEditor.Windows
|
||||
[NoSerialize, DefaultValue(1.0f), Limit(0.05f, 5, 0)]
|
||||
[EditorOrder(1400), EditorDisplay("Quality")]
|
||||
[Tooltip("The scale of the rendering resolution relative to the output dimensions. If lower than 1 the scene and postprocessing will be rendered at a lower resolution and upscaled to the output backbuffer.")]
|
||||
public float RenderingPercentage
|
||||
public float RenderScale
|
||||
{
|
||||
get => MainRenderTask.Instance.RenderingPercentage;
|
||||
set => MainRenderTask.Instance.RenderingPercentage = value;
|
||||
get => MainRenderTask.Instance.RenderScale;
|
||||
set => MainRenderTask.Instance.RenderScale = value;
|
||||
}
|
||||
|
||||
[NoSerialize, DefaultValue(RenderingUpscaleLocation.AfterAntiAliasingPass), VisibleIf(nameof(UpscaleLocation_Visible))]
|
||||
@@ -113,7 +113,7 @@ namespace FlaxEditor.Windows
|
||||
set => MainRenderTask.Instance.UpscaleLocation = value;
|
||||
}
|
||||
|
||||
private bool UpscaleLocation_Visible => MainRenderTask.Instance.RenderingPercentage < 1.0f;
|
||||
private bool UpscaleLocation_Visible => MainRenderTask.Instance.RenderScale < 1.0f;
|
||||
|
||||
[NoSerialize, DefaultValue(1.0f), Limit(0, 1)]
|
||||
[EditorOrder(1500), EditorDisplay("Quality"), Tooltip("The global density scale for all foliage instances. The default value is 1. Use values from range 0-1. Lower values decrease amount of foliage instances in-game. Use it to tweak game performance for slower devices.")]
|
||||
|
||||
@@ -205,10 +205,9 @@ bool BehaviorKnowledge::Set(const StringAnsiView& path, const Variant& value)
|
||||
|
||||
bool BehaviorKnowledge::HasGoal(ScriptingTypeHandle type) const
|
||||
{
|
||||
for (int32 i = 0; i < Goals.Count(); i++)
|
||||
for (const Variant& goal : Goals)
|
||||
{
|
||||
const ScriptingTypeHandle goalType = Scripting::FindScriptingType(Goals[i].Type.GetTypeName());
|
||||
if (goalType == type)
|
||||
if (goal.Type.GetScriptingType() == type)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -218,8 +217,7 @@ const Variant& BehaviorKnowledge::GetGoal(ScriptingTypeHandle type) const
|
||||
{
|
||||
for (const Variant& goal : Goals)
|
||||
{
|
||||
const ScriptingTypeHandle goalType = Scripting::FindScriptingType(goal.Type.GetTypeName());
|
||||
if (goalType == type)
|
||||
if (goal.Type.GetScriptingType() == type)
|
||||
return goal;
|
||||
}
|
||||
return Variant::Null;
|
||||
@@ -242,10 +240,9 @@ void BehaviorKnowledge::RemoveGoal(ScriptingTypeHandle type)
|
||||
{
|
||||
for (int32 i = 0; i < Goals.Count(); i++)
|
||||
{
|
||||
const ScriptingTypeHandle goalType = Scripting::FindScriptingType(Goals[i].Type.GetTypeName());
|
||||
if (goalType == type)
|
||||
if (Goals[i].Type.GetScriptingType() == type)
|
||||
{
|
||||
Goals.RemoveAt(i);
|
||||
Goals.RemoveAtKeepOrder(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ void VisualScriptExecutor::ProcessGroupTools(Box* box, Node* node, Value& value)
|
||||
obj = Value::Null;
|
||||
#else
|
||||
const ScriptingTypeHandle type = Scripting::FindScriptingType(StringAnsiView(typeNameAnsi.Get(), typeName.Length()));
|
||||
const ScriptingTypeHandle objType = Scripting::FindScriptingType(obj.Type.GetTypeName());
|
||||
const ScriptingTypeHandle objType = obj.Type.GetScriptingType();
|
||||
if (!type || !objType || !objType.IsSubclassOf(type))
|
||||
obj = Value::Null;
|
||||
#endif
|
||||
|
||||
@@ -125,7 +125,7 @@ VariantType::VariantType(Types type, const StringAnsiView& typeName, bool static
|
||||
VariantType::VariantType(Types type, const ScriptingType& sType)
|
||||
: VariantType(type)
|
||||
{
|
||||
SetTypeName(sType.Fullname, sType.Module->CanReload);
|
||||
SetTypeName(sType.Fullname, !sType.Module->CanReload);
|
||||
}
|
||||
|
||||
VariantType::VariantType(Types type, const MClass* klass)
|
||||
@@ -345,13 +345,13 @@ void VariantType::SetTypeName(const StringAnsiView& typeName, bool staticName)
|
||||
|
||||
void VariantType::SetTypeName(const ScriptingType& type)
|
||||
{
|
||||
SetTypeName(type.Fullname, type.Module->CanReload);
|
||||
SetTypeName(type.Fullname, !type.Module->CanReload);
|
||||
}
|
||||
|
||||
void VariantType::SetTypeName(const MClass& klass)
|
||||
{
|
||||
#if USE_CSHARP
|
||||
SetTypeName(klass.GetFullName(), klass.GetAssembly()->CanReload());
|
||||
SetTypeName(klass.GetFullName(), !klass.GetAssembly()->CanReload());
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -362,6 +362,11 @@ const char* VariantType::GetTypeName() const
|
||||
return InBuiltTypesTypeNames[Type];
|
||||
}
|
||||
|
||||
ScriptingTypeHandle VariantType::GetScriptingType() const
|
||||
{
|
||||
return Scripting::FindScriptingType(GetTypeName());
|
||||
}
|
||||
|
||||
VariantType VariantType::GetElementType() const
|
||||
{
|
||||
if (Type == Array)
|
||||
|
||||
@@ -151,6 +151,7 @@ public:
|
||||
void SetTypeName(const ScriptingType& type);
|
||||
void SetTypeName(const MClass& klass);
|
||||
const char* GetTypeName() const;
|
||||
ScriptingTypeHandle GetScriptingType() const;
|
||||
VariantType GetElementType() const;
|
||||
// Drops custom type name into the name allocated by the scripting module to reduce memory allocations when referencing types.
|
||||
void Inline();
|
||||
@@ -420,6 +421,15 @@ public:
|
||||
return MoveTemp(v);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static typename TEnableIf<TIsEnum<T>::Value, Variant>::Type Enum(const T value)
|
||||
{
|
||||
Variant v;
|
||||
v.SetType(VariantType(VariantType::Enum, StaticType<T>().GetType()));
|
||||
v.AsUint64 = (uint64)value;
|
||||
return MoveTemp(v);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static typename TEnableIf<!TIsEnum<T>::Value && !TIsPointer<T>::Value, Variant>::Type Structure(VariantType&& type, const T& value)
|
||||
{
|
||||
|
||||
@@ -85,7 +85,7 @@ struct CommandData
|
||||
else if (value.Type.Type == VariantType::Structure)
|
||||
{
|
||||
// Prettify structure printing
|
||||
ScriptingTypeHandle resultType = Scripting::FindScriptingType(value.Type.GetTypeName());
|
||||
ScriptingTypeHandle resultType = value.Type.GetScriptingType();
|
||||
if (resultType)
|
||||
{
|
||||
Array<void*> fields;
|
||||
|
||||
@@ -353,8 +353,11 @@ Viewport SceneRenderTask::GetViewport() const
|
||||
viewport = Buffers->GetViewport();
|
||||
else
|
||||
viewport = Viewport(0, 0, 1280, 720);
|
||||
viewport.Width *= RenderingPercentage;
|
||||
viewport.Height *= RenderingPercentage;
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
float renderScale = RenderingPercentage * RenderScale;
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||
viewport.Width *= renderScale;
|
||||
viewport.Height *= renderScale;
|
||||
return viewport;
|
||||
}
|
||||
|
||||
@@ -394,13 +397,16 @@ void SceneRenderTask::OnBegin(GPUContext* context)
|
||||
}
|
||||
|
||||
// Setup render buffers for the output rendering resolution
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
float renderScale = RenderingPercentage * RenderScale;
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||
if (Output)
|
||||
{
|
||||
Buffers->Init((int32)((float)Output->Width() * RenderingPercentage), (int32)((float)Output->Height() * RenderingPercentage));
|
||||
Buffers->Init((int32)((float)Output->Width() * renderScale), (int32)((float)Output->Height() * renderScale));
|
||||
}
|
||||
else if (SwapChain)
|
||||
{
|
||||
Buffers->Init((int32)((float)SwapChain->GetWidth() * RenderingPercentage), (int32)((float)SwapChain->GetHeight() * RenderingPercentage));
|
||||
Buffers->Init((int32)((float)SwapChain->GetWidth() * renderScale), (int32)((float)SwapChain->GetHeight() * renderScale));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,7 +440,10 @@ bool SceneRenderTask::Resize(int32 width, int32 height)
|
||||
PROFILE_MEM(Graphics);
|
||||
if (Output && Output->Resize(width, height))
|
||||
return true;
|
||||
if (Buffers && Buffers->Init((int32)((float)width * RenderingPercentage), (int32)((float)height * RenderingPercentage)))
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
float renderScale = RenderingPercentage * RenderScale;
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||
if (Buffers && Buffers->Init((int32)((float)width * renderScale), (int32)((float)height * renderScale)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -477,12 +486,6 @@ void MainRenderTask::OnBegin(GPUContext* context)
|
||||
// Use the main camera for the game (can be later overriden in Begin event by external code)
|
||||
Camera = Camera::GetMainCamera();
|
||||
|
||||
#if !USE_EDITOR
|
||||
// Sync render buffers size with the backbuffer
|
||||
const auto size = Screen::GetSize();
|
||||
Buffers->Init((int32)(size.X * RenderingPercentage), (int32)(size.Y * RenderingPercentage));
|
||||
#endif
|
||||
|
||||
SceneRenderTask::OnBegin(context);
|
||||
}
|
||||
|
||||
@@ -507,3 +510,10 @@ RenderContextBatch::RenderContextBatch(const RenderContext& context)
|
||||
Contexts.Add(context);
|
||||
EnableAsync = JobSystem::GetThreadsCount() > 1;
|
||||
}
|
||||
|
||||
void RenderContextBatch::FlushWaitLabels()
|
||||
{
|
||||
for (const int64 label : WaitLabels)
|
||||
JobSystem::Wait(label);
|
||||
WaitLabels.Clear();
|
||||
}
|
||||
|
||||
@@ -268,8 +268,14 @@ public:
|
||||
|
||||
/// <summary>
|
||||
/// The scale of the rendering resolution relative to the output dimensions. If lower than 1 the scene and postprocessing will be rendered at a lower resolution and upscaled to the output backbuffer.
|
||||
/// [Deprecated in v1.13]
|
||||
/// </summary>
|
||||
API_FIELD() float RenderingPercentage = 1.0f;
|
||||
API_FIELD() DEPRECATED("Use RenderScale instead.") float RenderingPercentage = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The scale of the rendering resolution relative to the output dimensions. If lower than 1 the scene and postprocessing will be rendered at a lower resolution and upscaled to the output backbuffer.
|
||||
/// </summary>
|
||||
API_FIELD() float RenderScale = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The image resolution upscale location within rendering pipeline. Unused if RenderingPercentage is 1.
|
||||
@@ -533,4 +539,9 @@ API_STRUCT(NoDefault) struct FLAXENGINE_API RenderContextBatch
|
||||
{
|
||||
return Contexts.Get()[0];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Waits for all scheduled async jobs to complete and clears WaitLabels.
|
||||
/// </summary>
|
||||
void FlushWaitLabels();
|
||||
};
|
||||
|
||||
@@ -64,7 +64,7 @@ Actor* Prefab::GetDefaultInstance()
|
||||
// Skip if not loaded
|
||||
if (!IsLoaded())
|
||||
{
|
||||
LOG(Warning, "Cannot instantiate object from not loaded prefab asset.");
|
||||
LOG(Warning, "Cannot instantiate object from not loaded prefab asset ({}, {})", GetPath(), GetID());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -184,6 +184,15 @@ PhysicsScene* Physics::FindScene(const StringView& name)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Physics::DeleteScene(PhysicsScene* scene)
|
||||
{
|
||||
if (scene == nullptr || scene == DefaultScene)
|
||||
return;
|
||||
scene->CollectResults();
|
||||
Scenes.RemoveKeepOrder(scene);
|
||||
Delete(scene);
|
||||
}
|
||||
|
||||
bool Physics::GetAutoSimulation()
|
||||
{
|
||||
return !DefaultScene || DefaultScene->GetAutoSimulation();
|
||||
|
||||
@@ -32,6 +32,11 @@ API_CLASS(Static) class FLAXENGINE_API Physics
|
||||
/// </summary>
|
||||
API_FUNCTION() static PhysicsScene* FindScene(const StringView& name);
|
||||
|
||||
/// <summary>
|
||||
/// Delete an existing scene (excluding the default one).
|
||||
/// </summary>
|
||||
API_FUNCTION() static void DeleteScene(PhysicsScene* scene);
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// The automatic simulation feature. True if perform physics simulation after on fixed update by auto, otherwise user should do it.
|
||||
|
||||
@@ -356,9 +356,7 @@ void Renderer::DrawActors(RenderContext& renderContext, const Array<Actor*>& cus
|
||||
Level::DrawActors(renderContextBatch, SceneRendering::DrawCategory::SceneDraw);
|
||||
Level::DrawActors(renderContextBatch, SceneRendering::DrawCategory::SceneDrawAsync);
|
||||
JobSystem::SetJobStartingOnDispatch(true);
|
||||
for (const int64 label : renderContextBatch.WaitLabels)
|
||||
JobSystem::Wait(label);
|
||||
renderContextBatch.WaitLabels.Clear();
|
||||
renderContextBatch.FlushWaitLabels();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,9 +481,7 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
|
||||
|
||||
// Wait for async jobs to finish
|
||||
JobSystem::SetJobStartingOnDispatch(true);
|
||||
for (const int64 label : renderContextBatch.WaitLabels)
|
||||
JobSystem::Wait(label);
|
||||
renderContextBatch.WaitLabels.Clear();
|
||||
renderContextBatch.FlushWaitLabels();
|
||||
|
||||
// Perform custom post-scene drawing (eg. GPU dispatches used by VFX)
|
||||
for (int32 i = 0; i < renderContextBatch.Contexts.Count(); i++)
|
||||
@@ -737,7 +733,9 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
|
||||
}
|
||||
|
||||
// Upscaling after scene rendering but before post processing
|
||||
bool useUpscaling = task->RenderingPercentage < 1.0f;
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
bool useUpscaling = task->RenderingPercentage * task->RenderScale < 1.0f;
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||
const Viewport outputViewport = task->GetOutputViewport();
|
||||
if (useUpscaling && setup.UpscaleLocation == RenderingUpscaleLocation::BeforePostProcessingPass)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
|
||||
namespace FlaxEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Changes enum serialization to use string names instead of integer values. This makes saved data resilient to enum reordering or changes in values (but not to renaming enums). Deserialization accepts both string names and integer values for backward compatibility.
|
||||
/// </summary>
|
||||
/// <seealso cref="System.Attribute" />
|
||||
[AttributeUsage(AttributeTargets.Enum)]
|
||||
public sealed class EnumStringAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -204,7 +204,7 @@ ScriptingType::ScriptingType(const StringAnsiView& fullname, BinaryModule* modul
|
||||
Struct.SetField = setField;
|
||||
}
|
||||
|
||||
ScriptingType::ScriptingType(const StringAnsiView& fullname, BinaryModule* module, int32 size, EnumItem* items)
|
||||
ScriptingType::ScriptingType(const StringAnsiView& fullname, BinaryModule* module, int32 size, EnumItem* items, bool stringSerialization)
|
||||
: ManagedClass(nullptr)
|
||||
, Module(module)
|
||||
, InitRuntime(DefaultInitRuntime)
|
||||
@@ -215,6 +215,7 @@ ScriptingType::ScriptingType(const StringAnsiView& fullname, BinaryModule* modul
|
||||
, Size(size)
|
||||
{
|
||||
Enum.Items = items;
|
||||
Enum.StringSerialization = stringSerialization;
|
||||
}
|
||||
|
||||
ScriptingType::ScriptingType(const StringAnsiView& fullname, BinaryModule* module, InitRuntimeHandler initRuntime, SetupScriptVTableHandler setupScriptVTable, SetupScriptObjectVTableHandler setupScriptObjectVTable, GetInterfaceWrapper getInterfaceWrapper)
|
||||
@@ -270,6 +271,7 @@ ScriptingType::ScriptingType(const ScriptingType& other)
|
||||
break;
|
||||
case ScriptingTypes::Enum:
|
||||
Enum.Items = other.Enum.Items;
|
||||
Enum.StringSerialization = other.Enum.StringSerialization;
|
||||
break;
|
||||
case ScriptingTypes::Interface:
|
||||
Interface.SetupScriptVTable = other.Interface.SetupScriptVTable;
|
||||
@@ -323,6 +325,7 @@ ScriptingType::ScriptingType(ScriptingType&& other)
|
||||
break;
|
||||
case ScriptingTypes::Enum:
|
||||
Enum.Items = other.Enum.Items;
|
||||
Enum.StringSerialization = other.Enum.StringSerialization;
|
||||
break;
|
||||
case ScriptingTypes::Interface:
|
||||
Interface.SetupScriptVTable = other.Interface.SetupScriptVTable;
|
||||
@@ -604,71 +607,57 @@ StringAnsiView ScriptingType::GetName() const
|
||||
return Fullname;
|
||||
}
|
||||
|
||||
#if BUILD_DEBUG || USE_EDITOR
|
||||
#define INIT_TYPE(...) \
|
||||
module->Types.AddUninitialized(); \
|
||||
new(module->Types.Get() + TypeIndex)ScriptingType(fullname, module, ##__VA_ARGS__); \
|
||||
if (module->TypeNameToTypeIndex.ContainsKey(fullname)) \
|
||||
LOG(Error, "Duplicated native typename {0} from module {1}.", String(fullname), String(module->GetName())); \
|
||||
module->TypeNameToTypeIndex[fullname] = TypeIndex;
|
||||
#else
|
||||
#define INIT_TYPE(...) \
|
||||
module->Types.AddUninitialized(); \
|
||||
new(module->Types.Get() + TypeIndex)ScriptingType(fullname, module, ##__VA_ARGS__); \
|
||||
module->TypeNameToTypeIndex[fullname] = TypeIndex;
|
||||
#endif
|
||||
|
||||
ScriptingTypeInitializer::ScriptingTypeInitializer(BinaryModule* module, const StringAnsiView& fullname, int32 size, ScriptingType::InitRuntimeHandler initRuntime, ScriptingType::SpawnHandler spawn, ScriptingTypeInitializer* baseType, ScriptingType::SetupScriptVTableHandler setupScriptVTable, ScriptingType::SetupScriptObjectVTableHandler setupScriptObjectVTable, const ScriptingType::InterfaceImplementation* interfaces)
|
||||
: ScriptingTypeHandle(module, module->Types.Count())
|
||||
{
|
||||
// Script
|
||||
module->Types.AddUninitialized();
|
||||
new(module->Types.Get() + TypeIndex)ScriptingType(fullname, module, size, initRuntime, spawn, baseType, setupScriptVTable, setupScriptObjectVTable, interfaces);
|
||||
#if BUILD_DEBUG
|
||||
if (module->TypeNameToTypeIndex.ContainsKey(fullname))
|
||||
LOG(Error, "Duplicated native typename {0} from module {1}.", String(fullname), String(module->GetName()));
|
||||
#endif
|
||||
module->TypeNameToTypeIndex[fullname] = TypeIndex;
|
||||
INIT_TYPE(size, initRuntime, spawn, baseType, setupScriptVTable, setupScriptObjectVTable, interfaces);
|
||||
}
|
||||
|
||||
ScriptingTypeInitializer::ScriptingTypeInitializer(BinaryModule* module, const StringAnsiView& fullname, int32 size, ScriptingType::InitRuntimeHandler initRuntime, ScriptingType::Ctor ctor, ScriptingType::Dtor dtor, ScriptingTypeInitializer* baseType, const ScriptingType::InterfaceImplementation* interfaces)
|
||||
: ScriptingTypeHandle(module, module->Types.Count())
|
||||
{
|
||||
// Class
|
||||
module->Types.AddUninitialized();
|
||||
new(module->Types.Get() + TypeIndex)ScriptingType(fullname, module, size, initRuntime, ctor, dtor, baseType, interfaces);
|
||||
#if BUILD_DEBUG
|
||||
if (module->TypeNameToTypeIndex.ContainsKey(fullname))
|
||||
LOG(Error, "Duplicated native typename {0} from module {1}.", String(fullname), String(module->GetName()));
|
||||
#endif
|
||||
module->TypeNameToTypeIndex[fullname] = TypeIndex;
|
||||
INIT_TYPE(size, initRuntime, ctor, dtor, baseType, interfaces);
|
||||
}
|
||||
|
||||
ScriptingTypeInitializer::ScriptingTypeInitializer(BinaryModule* module, const StringAnsiView& fullname, int32 size, ScriptingType::InitRuntimeHandler initRuntime, ScriptingType::Ctor ctor, ScriptingType::Dtor dtor, ScriptingType::Copy copy, ScriptingType::Box box, ScriptingType::Unbox unbox, ScriptingType::GetField getField, ScriptingType::SetField setField, ScriptingTypeInitializer* baseType, const ScriptingType::InterfaceImplementation* interfaces)
|
||||
: ScriptingTypeHandle(module, module->Types.Count())
|
||||
{
|
||||
// Structure
|
||||
module->Types.AddUninitialized();
|
||||
new(module->Types.Get() + TypeIndex)ScriptingType(fullname, module, size, initRuntime, ctor, dtor, copy, box, unbox, getField, setField, baseType, interfaces);
|
||||
#if BUILD_DEBUG
|
||||
if (module->TypeNameToTypeIndex.ContainsKey(fullname))
|
||||
LOG(Error, "Duplicated native typename {0} from module {1}.", String(fullname), String(module->GetName()));
|
||||
#endif
|
||||
module->TypeNameToTypeIndex[fullname] = TypeIndex;
|
||||
INIT_TYPE(size, initRuntime, ctor, dtor, copy, box, unbox, getField, setField, baseType, interfaces);
|
||||
}
|
||||
|
||||
ScriptingTypeInitializer::ScriptingTypeInitializer(BinaryModule* module, const StringAnsiView& fullname, int32 size, ScriptingType::EnumItem* items)
|
||||
ScriptingTypeInitializer::ScriptingTypeInitializer(BinaryModule* module, const StringAnsiView& fullname, int32 size, ScriptingType::EnumItem* items, bool stringSerialization)
|
||||
: ScriptingTypeHandle(module, module->Types.Count())
|
||||
{
|
||||
// Enum
|
||||
module->Types.AddUninitialized();
|
||||
new(module->Types.Get() + TypeIndex)ScriptingType(fullname, module, size, items);
|
||||
#if BUILD_DEBUG
|
||||
if (module->TypeNameToTypeIndex.ContainsKey(fullname))
|
||||
LOG(Error, "Duplicated native typename {0} from module {1}.", String(fullname), String(module->GetName()));
|
||||
#endif
|
||||
module->TypeNameToTypeIndex[fullname] = TypeIndex;
|
||||
INIT_TYPE(size, items, stringSerialization);
|
||||
}
|
||||
|
||||
ScriptingTypeInitializer::ScriptingTypeInitializer(BinaryModule* module, const StringAnsiView& fullname, ScriptingType::InitRuntimeHandler initRuntime, ScriptingType::SetupScriptVTableHandler setupScriptVTable, ScriptingType::SetupScriptObjectVTableHandler setupScriptObjectVTable, ScriptingType::GetInterfaceWrapper getInterfaceWrapper)
|
||||
: ScriptingTypeHandle(module, module->Types.Count())
|
||||
{
|
||||
// Interface
|
||||
module->Types.AddUninitialized();
|
||||
new(module->Types.Get() + TypeIndex)ScriptingType(fullname, module, initRuntime, setupScriptVTable, setupScriptObjectVTable, getInterfaceWrapper);
|
||||
#if BUILD_DEBUG
|
||||
if (module->TypeNameToTypeIndex.ContainsKey(fullname))
|
||||
LOG(Error, "Duplicated native typename {0} from module {1}.", String(fullname), String(module->GetName()));
|
||||
#endif
|
||||
module->TypeNameToTypeIndex[fullname] = TypeIndex;
|
||||
INIT_TYPE(initRuntime, setupScriptVTable, setupScriptObjectVTable, getInterfaceWrapper);
|
||||
}
|
||||
|
||||
#undef INIT_TYPE
|
||||
|
||||
CriticalSection BinaryModule::Locker;
|
||||
|
||||
BinaryModule::BinaryModulesList& BinaryModule::GetModules()
|
||||
|
||||
@@ -266,6 +266,8 @@ struct FLAXENGINE_API ScriptingType
|
||||
{
|
||||
// Enum items table (the last item name is null)
|
||||
EnumItem* Items;
|
||||
// Enum uses string names serialization instead of integer values.
|
||||
bool StringSerialization;
|
||||
} Enum;
|
||||
|
||||
struct
|
||||
@@ -290,7 +292,7 @@ struct FLAXENGINE_API ScriptingType
|
||||
ScriptingType(const StringAnsiView& fullname, BinaryModule* module, int32 size, InitRuntimeHandler initRuntime = DefaultInitRuntime, SpawnHandler spawn = DefaultSpawn, ScriptingTypeInitializer* baseType = nullptr, SetupScriptVTableHandler setupScriptVTable = nullptr, SetupScriptObjectVTableHandler setupScriptObjectVTable = nullptr, const InterfaceImplementation* interfaces = nullptr);
|
||||
ScriptingType(const StringAnsiView& fullname, BinaryModule* module, int32 size, InitRuntimeHandler initRuntime, Ctor ctor, Dtor dtor, ScriptingTypeInitializer* baseType, const InterfaceImplementation* interfaces = nullptr);
|
||||
ScriptingType(const StringAnsiView& fullname, BinaryModule* module, int32 size, InitRuntimeHandler initRuntime, Ctor ctor, Dtor dtor, Copy copy, Box box, Unbox unbox, GetField getField, SetField setField, ScriptingTypeInitializer* baseType, const InterfaceImplementation* interfaces = nullptr);
|
||||
ScriptingType(const StringAnsiView& fullname, BinaryModule* module, int32 size, EnumItem* items);
|
||||
ScriptingType(const StringAnsiView& fullname, BinaryModule* module, int32 size, EnumItem* items, bool stringSerialization);
|
||||
ScriptingType(const StringAnsiView& fullname, BinaryModule* module, InitRuntimeHandler initRuntime, SetupScriptVTableHandler setupScriptVTable, SetupScriptObjectVTableHandler setupScriptObjectVTable, GetInterfaceWrapper getInterfaceWrapper);
|
||||
ScriptingType(const ScriptingType& other);
|
||||
ScriptingType(ScriptingType&& other);
|
||||
@@ -339,7 +341,7 @@ struct FLAXENGINE_API ScriptingTypeInitializer : ScriptingTypeHandle
|
||||
ScriptingTypeInitializer(BinaryModule* module, const StringAnsiView& fullname, int32 size, ScriptingType::InitRuntimeHandler initRuntime = ScriptingType::DefaultInitRuntime, ScriptingType::SpawnHandler spawn = ScriptingType::DefaultSpawn, ScriptingTypeInitializer* baseType = nullptr, ScriptingType::SetupScriptVTableHandler setupScriptVTable = nullptr, ScriptingType::SetupScriptObjectVTableHandler setupScriptObjectVTable = nullptr, const ScriptingType::InterfaceImplementation* interfaces = nullptr);
|
||||
ScriptingTypeInitializer(BinaryModule* module, const StringAnsiView& fullname, int32 size, ScriptingType::InitRuntimeHandler initRuntime, ScriptingType::Ctor ctor, ScriptingType::Dtor dtor, ScriptingTypeInitializer* baseType = nullptr, const ScriptingType::InterfaceImplementation* interfaces = nullptr);
|
||||
ScriptingTypeInitializer(BinaryModule* module, const StringAnsiView& fullname, int32 size, ScriptingType::InitRuntimeHandler initRuntime, ScriptingType::Ctor ctor, ScriptingType::Dtor dtor, ScriptingType::Copy copy, ScriptingType::Box box, ScriptingType::Unbox unbox, ScriptingType::GetField getField, ScriptingType::SetField setField, ScriptingTypeInitializer* baseType = nullptr, const ScriptingType::InterfaceImplementation* interfaces = nullptr);
|
||||
ScriptingTypeInitializer(BinaryModule* module, const StringAnsiView& fullname, int32 size, ScriptingType::EnumItem* items);
|
||||
ScriptingTypeInitializer(BinaryModule* module, const StringAnsiView& fullname, int32 size, ScriptingType::EnumItem* items, bool stringSerialization);
|
||||
ScriptingTypeInitializer(BinaryModule* module, const StringAnsiView& fullname, ScriptingType::InitRuntimeHandler initRuntime, ScriptingType::SetupScriptVTableHandler setupScriptVTable, ScriptingType::SetupScriptObjectVTableHandler setupScriptObjectVTable, ScriptingType::GetInterfaceWrapper getInterfaceWrapper);
|
||||
};
|
||||
|
||||
|
||||
+13
-5
@@ -5,6 +5,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace FlaxEngine.Json.JsonCustomSerializers
|
||||
@@ -44,6 +45,13 @@ namespace FlaxEngine.Json.JsonCustomSerializers
|
||||
((JsonObjectContract)contract).ItemReferenceLoopHandling = ReferenceLoopHandling.Serialize;
|
||||
}
|
||||
|
||||
// Check if use enum serialization as string
|
||||
var type = Nullable.GetUnderlyingType(objectType) ?? objectType;
|
||||
if (type.IsEnum && type.GetCustomAttribute<EnumStringAttribute>() != null)
|
||||
{
|
||||
contract.Converter = new StringEnumConverter();
|
||||
}
|
||||
|
||||
return contract;
|
||||
}
|
||||
|
||||
@@ -53,19 +61,19 @@ namespace FlaxEngine.Json.JsonCustomSerializers
|
||||
var contract = base.CreateDictionaryContract(objectType);
|
||||
|
||||
// Override contract to save enums keys as integer
|
||||
if (contract.DictionaryKeyType?.IsEnum ?? false)
|
||||
var keyType = contract.DictionaryKeyType;
|
||||
if ((keyType?.IsEnum ?? false) && keyType.GetCustomAttribute<EnumStringAttribute>() == null)
|
||||
{
|
||||
var enumType = contract.DictionaryKeyType;
|
||||
contract.DictionaryKeyResolver = name =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var e = Enum.Parse(enumType, name);
|
||||
var e = Enum.Parse(keyType, name);
|
||||
name = Convert.ToInt32(e).ToString();
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Ignore errors
|
||||
Debug.Logger.LogHandler.LogWrite(LogType.Warning, $"Failed to parse enum '{name}' as {keyType.Name}: {ex.Message}");
|
||||
}
|
||||
return name;
|
||||
};
|
||||
|
||||
@@ -49,6 +49,54 @@ void ISerializable::DeserializeIfExists(DeserializeStream& stream, const char* m
|
||||
var = defaultValue;\
|
||||
}
|
||||
|
||||
void Serialization::SerializeEnum(ISerializable::SerializeStream& stream, uint32 v, ScriptingTypeHandle typeHandle)
|
||||
{
|
||||
if (typeHandle)
|
||||
{
|
||||
// Check if serialize enum as string
|
||||
const ScriptingType& type = typeHandle.GetType();
|
||||
if (type.Type == ScriptingTypes::Enum && type.Enum.StringSerialization)
|
||||
{
|
||||
const auto items = type.Enum.Items;
|
||||
for (int32 i = 0; items[i].Name; i++)
|
||||
{
|
||||
if (items[i].Value == v)
|
||||
{
|
||||
stream.String(items[i].Name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stream.Uint(v);
|
||||
}
|
||||
|
||||
int32 Serialization::DeserializeEnum(ISerializable::DeserializeStream& stream, ScriptingTypeHandle typeHandle)
|
||||
{
|
||||
if (stream.IsString() && typeHandle)
|
||||
{
|
||||
// Deserialize enum from string
|
||||
const ScriptingType& type = typeHandle.GetType();
|
||||
if (type.Type == ScriptingTypes::Enum)
|
||||
{
|
||||
const auto str = stream.GetStringAnsiView();
|
||||
const auto items = type.Enum.Items;
|
||||
for (int32 i = 0; items[i].Name; i++)
|
||||
{
|
||||
if (str == items[i].Name)
|
||||
{
|
||||
return (int32)items[i].Value;
|
||||
}
|
||||
}
|
||||
int32 result;
|
||||
if (!StringUtils::Parse(stream.GetString(), &result))
|
||||
return result;
|
||||
LOG(Warning, "Failed to parse enum '{}' as {}", str.ToString(), type.Fullname.ToString());
|
||||
}
|
||||
}
|
||||
return DeserializeInt(stream);
|
||||
}
|
||||
|
||||
bool Serialization::ShouldSerialize(const VariantType& v, const void* otherObj)
|
||||
{
|
||||
return !otherObj || v != *(VariantType*)otherObj;
|
||||
@@ -129,7 +177,6 @@ void Serialization::Serialize(ISerializable::SerializeStream& stream, const Vari
|
||||
stream.Int64(v.AsInt64);
|
||||
break;
|
||||
case VariantType::Uint64:
|
||||
case VariantType::Enum:
|
||||
stream.Uint64(v.AsUint64);
|
||||
break;
|
||||
case VariantType::Float:
|
||||
@@ -222,6 +269,9 @@ void Serialization::Serialize(ISerializable::SerializeStream& stream, const Vari
|
||||
else
|
||||
stream.String("", 0);
|
||||
break;
|
||||
case VariantType::Enum:
|
||||
SerializeEnum(stream, (int32)v.AsUint64, v.Type.GetScriptingType());
|
||||
break;
|
||||
case VariantType::ManagedObject:
|
||||
case VariantType::Structure:
|
||||
{
|
||||
@@ -276,7 +326,6 @@ void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Varian
|
||||
v.AsInt64 = value.GetInt64();
|
||||
break;
|
||||
case VariantType::Uint64:
|
||||
case VariantType::Enum:
|
||||
v.AsUint64 = value.GetUint64();
|
||||
break;
|
||||
case VariantType::Float:
|
||||
@@ -371,6 +420,9 @@ void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Varian
|
||||
CHECK(value.IsString());
|
||||
v.SetTypename(value.GetStringAnsiView());
|
||||
break;
|
||||
case VariantType::Enum:
|
||||
v.AsInt64 = DeserializeEnum(value, v.Type.GetScriptingType());
|
||||
break;
|
||||
case VariantType::ManagedObject:
|
||||
case VariantType::Structure:
|
||||
{
|
||||
@@ -408,7 +460,7 @@ void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Varian
|
||||
|
||||
bool Serialization::ShouldSerialize(const Guid& v, const void* otherObj)
|
||||
{
|
||||
return v.IsValid();
|
||||
return !otherObj || v != *(Guid*)otherObj;
|
||||
}
|
||||
|
||||
void Serialization::Serialize(ISerializable::SerializeStream& stream, const Guid& v, const void* otherObj)
|
||||
@@ -427,10 +479,12 @@ void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Guid&
|
||||
const char* b = a + 8;
|
||||
const char* c = b + 8;
|
||||
const char* d = c + 8;
|
||||
StringUtils::ParseHex(a, 8, &v.A);
|
||||
StringUtils::ParseHex(b, 8, &v.B);
|
||||
StringUtils::ParseHex(c, 8, &v.C);
|
||||
StringUtils::ParseHex(d, 8, &v.D);
|
||||
bool failed = StringUtils::ParseHex(a, 8, &v.A);
|
||||
failed |= StringUtils::ParseHex(b, 8, &v.B);
|
||||
failed |= StringUtils::ParseHex(c, 8, &v.C);
|
||||
failed |= StringUtils::ParseHex(d, 8, &v.D);
|
||||
if (failed)
|
||||
v = Guid::Empty;
|
||||
}
|
||||
|
||||
bool Serialization::ShouldSerialize(const DateTime& v, const void* otherObj)
|
||||
|
||||
@@ -38,12 +38,16 @@ namespace Serialization
|
||||
int32 result = 0;
|
||||
if (stream.IsInt())
|
||||
result = stream.GetInt();
|
||||
else if (stream.IsInt64())
|
||||
result = (int32)stream.GetInt64();
|
||||
else if (stream.IsFloat())
|
||||
result = (int32)stream.GetFloat();
|
||||
else if (stream.IsString())
|
||||
StringUtils::Parse(stream.GetString(), &result);
|
||||
return result;
|
||||
}
|
||||
FLAXENGINE_API void SerializeEnum(ISerializable::SerializeStream& stream, uint32 v, ScriptingTypeHandle typeHandle);
|
||||
FLAXENGINE_API int32 DeserializeEnum(ISerializable::DeserializeStream& stream, ScriptingTypeHandle typeHandle);
|
||||
|
||||
// In-build types
|
||||
|
||||
@@ -226,12 +230,12 @@ namespace Serialization
|
||||
template<typename T>
|
||||
inline typename TEnableIf<TIsEnum<T>::Value>::Type Serialize(ISerializable::SerializeStream& stream, const T& v, const void* otherObj)
|
||||
{
|
||||
stream.Uint((uint32)v);
|
||||
SerializeEnum(stream, (uint32)v, StaticType<T>());
|
||||
}
|
||||
template<typename T>
|
||||
inline typename TEnableIf<TIsEnum<T>::Value>::Type Deserialize(ISerializable::DeserializeStream& stream, T& v, ISerializeModifier* modifier)
|
||||
{
|
||||
v = (T)DeserializeInt(stream);
|
||||
v = (T)DeserializeEnum(stream, StaticType<T>());
|
||||
}
|
||||
|
||||
// Common types
|
||||
|
||||
@@ -766,7 +766,7 @@ void VisjectExecutor::ProcessGroupPacking(Box* box, Node* node, Value& value)
|
||||
structureValue = Variant::Cast(structureValue, typeVariantType);
|
||||
}
|
||||
structureValue.InvertInline(); // Extract any Float3/Int32 into Structure type from inlined format
|
||||
const ScriptingTypeHandle structureValueTypeHandle = Scripting::FindScriptingType(structureValue.Type.GetTypeName());
|
||||
const ScriptingTypeHandle structureValueTypeHandle = structureValue.Type.GetScriptingType();
|
||||
if (structureValue.Type.Type != VariantType::Structure || typeHandle != structureValueTypeHandle)
|
||||
{
|
||||
OnError(node, box, String::Format(TEXT("Cannot unpack value of type {0} to structure of type {1}"), structureValue.Type, typeName));
|
||||
|
||||
@@ -203,11 +203,11 @@ namespace Flax.Build.Bindings
|
||||
|
||||
var fullname = apiType.FullNameManaged;
|
||||
if (apiType.IsEnum)
|
||||
return $"Variant::Enum(VariantType(VariantType::Enum, StringAnsiView(\"{fullname}\", {fullname.Length})), {value})";
|
||||
return $"Variant::Enum(VariantType(VariantType::Enum, StringAnsiView(\"{fullname}\", {fullname.Length}), !USE_EDITOR), {value})";
|
||||
if (apiType.IsStruct && !CppInBuildVariantStructures.Contains(apiType.Name))
|
||||
{
|
||||
if (apiType.IsInBuild)
|
||||
return $"Variant::Structure(VariantType(VariantType::Structure, StringAnsiView(\"{fullname}\", {fullname.Length})), {(typeInfo.IsPtr ? "*" + value : value)})";
|
||||
return $"Variant::Structure(VariantType(VariantType::Structure, StringAnsiView(\"{fullname}\", {fullname.Length}), !USE_EDITOR), {(typeInfo.IsPtr ? "*" + value : value)})";
|
||||
return $"Variant::Structure(VariantType(VariantType::Structure, {apiType.FullNameNative}::TypeInitializer.GetType()), {(typeInfo.IsPtr ? "*" + value : value)})";
|
||||
}
|
||||
}
|
||||
@@ -269,7 +269,7 @@ namespace Flax.Build.Bindings
|
||||
{
|
||||
var elementType = FindApiTypeInfo(buildData, typeInfo.GenericArgs[0], caller);
|
||||
var elementName = $"{(elementType != null ? elementType.FullNameManaged : typeInfo.GenericArgs[0].Type)}[]";
|
||||
return $"VariantType(VariantType::Array, StringAnsiView(\"{elementName}\", {elementName.Length}))";
|
||||
return $"VariantType(VariantType::Array, StringAnsiView(\"{elementName}\", {elementName.Length}), !USE_EDITOR)";
|
||||
}
|
||||
if (typeInfo.Type == "Dictionary" && typeInfo.GenericArgs != null)
|
||||
return "VariantType(VariantType::Dictionary)";
|
||||
@@ -280,11 +280,11 @@ namespace Flax.Build.Bindings
|
||||
{
|
||||
var fullname = apiType.FullNameManaged;
|
||||
if (apiType.IsEnum)
|
||||
return $"VariantType(VariantType::Enum, StringAnsiView(\"{fullname}\", {fullname.Length}))";
|
||||
return $"VariantType(VariantType::Enum, StringAnsiView(\"{fullname}\", {fullname.Length}), !USE_EDITOR)";
|
||||
if (apiType.IsStruct)
|
||||
{
|
||||
if (apiType.IsInBuild)
|
||||
return $"VariantType(VariantType::Structure, StringAnsiView(\"{fullname}\", {fullname.Length}))";
|
||||
return $"VariantType(VariantType::Structure, StringAnsiView(\"{fullname}\", {fullname.Length}), !USE_EDITOR)";
|
||||
return $"VariantType(VariantType::Structure, {apiType.FullNameNative}::TypeInitializer.GetType())";
|
||||
}
|
||||
if (apiType.IsClass)
|
||||
@@ -2761,7 +2761,8 @@ namespace Flax.Build.Bindings
|
||||
contents.Append($"ScriptingTypeInitializer {enumTypeNameInternal}_TypeInitializer((BinaryModule*)GetBinaryModule{moduleInfo.Name}(), ");
|
||||
contents.Append($"StringAnsiView(\"{enumTypeNameManaged}\", {enumTypeNameManaged.Length}), ");
|
||||
contents.Append($"sizeof({enumTypeNameNative}), ");
|
||||
contents.Append($"{enumTypeNameInternal}Internal::Items);").AppendLine();
|
||||
var stringSerialization = enumInfo.Attributes != null && enumInfo.Attributes.Contains("EnumString") ? "true" : "false";
|
||||
contents.Append($"{enumTypeNameInternal}Internal::Items, {stringSerialization});").AppendLine();
|
||||
|
||||
contents.AppendLine($"template<> {moduleInfo.Name.ToUpperInvariant()}_API ScriptingTypeHandle StaticType<{enumTypeNameNative}>() {{ return {enumTypeNameInternal}_TypeInitializer; }}");
|
||||
}
|
||||
@@ -3103,7 +3104,7 @@ namespace Flax.Build.Bindings
|
||||
header.Append(" Variant result;").AppendLine();
|
||||
var apiType = FindApiTypeInfo(buildData, valueType, moduleInfo);
|
||||
var elementName = $"{(apiType != null ? apiType.FullNameManaged : valueType.Type)}[]";
|
||||
header.Append($" result.SetType(VariantType(VariantType::Array, StringAnsiView(\"{elementName}\", {elementName.Length})));").AppendLine();
|
||||
header.Append($" result.SetType(VariantType(VariantType::Array, StringAnsiView(\"{elementName}\", {elementName.Length}), !USE_EDITOR));").AppendLine();
|
||||
header.Append(" auto* array = reinterpret_cast<Array<Variant, HeapAllocation>*>(result.AsData);").AppendLine();
|
||||
header.Append(" array->Resize(length);").AppendLine();
|
||||
header.Append(" for (int32 i = 0; i < length; i++)").AppendLine();
|
||||
|
||||
Reference in New Issue
Block a user