Compare commits
1 Commits
emscripten
...
mac_change
| Author | SHA1 | Date | |
|---|---|---|---|
| fd5c50635c |
@@ -1,4 +1,4 @@
|
|||||||
# Redirect to our own Git LFS server
|
# Redirect to our own Git LFS server
|
||||||
[lfs]
|
[lfs]
|
||||||
#url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
|
url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
|
||||||
locksverify = false
|
locksverify = false
|
||||||
|
|||||||
BIN
Content/Shaders/Reflections.flax
LFS
BIN
Content/Shaders/Reflections.flax
LFS
Binary file not shown.
@@ -12,6 +12,6 @@ cd "`dirname "$0"`"
|
|||||||
bash ./Development/Scripts/Mac/CallBuildTool.sh --genproject "$@"
|
bash ./Development/Scripts/Mac/CallBuildTool.sh --genproject "$@"
|
||||||
|
|
||||||
# Build bindings for all editor configurations
|
# Build bindings for all editor configurations
|
||||||
echo Building C# bindings...
|
#echo Building C# bindings...
|
||||||
# TODO: Detect the correct architecture here
|
# TODO: Detect the correct architecture here
|
||||||
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=ARM64 -platform=Mac --buildTargets=FlaxEditor
|
#Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=ARM64 -platform=Mac --buildTargets=FlaxEditor
|
||||||
|
|||||||
@@ -141,11 +141,6 @@ API_ENUM() enum class BuildPlatform
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
API_ENUM(Attributes="EditorDisplay(null, \"Windows ARM64\")")
|
API_ENUM(Attributes="EditorDisplay(null, \"Windows ARM64\")")
|
||||||
WindowsARM64 = 15,
|
WindowsARM64 = 15,
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Web
|
|
||||||
/// </summary>
|
|
||||||
Web = 16,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -193,11 +188,6 @@ enum class DotNetAOTModes
|
|||||||
/// Use Mono AOT to cross-compile all used C# assemblies into native platform static libraries which can be linked into a single shared library.
|
/// Use Mono AOT to cross-compile all used C# assemblies into native platform static libraries which can be linked into a single shared library.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
MonoAOTStatic,
|
MonoAOTStatic,
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Target platform doesn't support .NET or it has been disabled.
|
|
||||||
/// </summary>
|
|
||||||
NoDotnet,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern FLAXENGINE_API const Char* ToString(const BuildPlatform platform);
|
extern FLAXENGINE_API const Char* ToString(const BuildPlatform platform);
|
||||||
|
|||||||
@@ -69,10 +69,6 @@
|
|||||||
#include "Platform/iOS/iOSPlatformTools.h"
|
#include "Platform/iOS/iOSPlatformTools.h"
|
||||||
#include "Engine/Platform/iOS/iOSPlatformSettings.h"
|
#include "Engine/Platform/iOS/iOSPlatformSettings.h"
|
||||||
#endif
|
#endif
|
||||||
#if PLATFORM_TOOLS_WEB
|
|
||||||
#include "Platform/Web/WebPlatformTools.h"
|
|
||||||
#include "Engine/Platform/Web/WebPlatformSettings.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace GameCookerImpl
|
namespace GameCookerImpl
|
||||||
{
|
{
|
||||||
@@ -155,8 +151,6 @@ const Char* ToString(const BuildPlatform platform)
|
|||||||
return TEXT("iOS ARM64");
|
return TEXT("iOS ARM64");
|
||||||
case BuildPlatform::WindowsARM64:
|
case BuildPlatform::WindowsARM64:
|
||||||
return TEXT("Windows ARM64");
|
return TEXT("Windows ARM64");
|
||||||
case BuildPlatform::Web:
|
|
||||||
return TEXT("Web");
|
|
||||||
default:
|
default:
|
||||||
return TEXT("");
|
return TEXT("");
|
||||||
}
|
}
|
||||||
@@ -189,8 +183,6 @@ const Char* ToString(const DotNetAOTModes mode)
|
|||||||
return TEXT("MonoAOTDynamic");
|
return TEXT("MonoAOTDynamic");
|
||||||
case DotNetAOTModes::MonoAOTStatic:
|
case DotNetAOTModes::MonoAOTStatic:
|
||||||
return TEXT("MonoAOTStatic");
|
return TEXT("MonoAOTStatic");
|
||||||
case DotNetAOTModes::NoDotnet:
|
|
||||||
return TEXT("NoDotnet");
|
|
||||||
default:
|
default:
|
||||||
return TEXT("");
|
return TEXT("");
|
||||||
}
|
}
|
||||||
@@ -315,10 +307,6 @@ void CookingData::GetBuildPlatformName(const Char*& platform, const Char*& archi
|
|||||||
platform = TEXT("Windows");
|
platform = TEXT("Windows");
|
||||||
architecture = TEXT("ARM64");
|
architecture = TEXT("ARM64");
|
||||||
break;
|
break;
|
||||||
case BuildPlatform::Web:
|
|
||||||
platform = TEXT("Web");
|
|
||||||
architecture = TEXT("x86");
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
LOG(Fatal, "Unknown or unsupported build platform.");
|
LOG(Fatal, "Unknown or unsupported build platform.");
|
||||||
}
|
}
|
||||||
@@ -473,11 +461,6 @@ PlatformTools* GameCooker::GetTools(BuildPlatform platform)
|
|||||||
case BuildPlatform::iOSARM64:
|
case BuildPlatform::iOSARM64:
|
||||||
result = New<iOSPlatformTools>();
|
result = New<iOSPlatformTools>();
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
#if PLATFORM_TOOLS_WEB
|
|
||||||
case BuildPlatform::Web:
|
|
||||||
result = New<WebPlatformTools>();
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
Tools.Add(platform, result);
|
Tools.Add(platform, result);
|
||||||
@@ -621,9 +604,6 @@ void GameCooker::GetCurrentPlatform(PlatformType& platform, BuildPlatform& build
|
|||||||
case PlatformType::iOS:
|
case PlatformType::iOS:
|
||||||
buildPlatform = BuildPlatform::iOSARM64;
|
buildPlatform = BuildPlatform::iOSARM64;
|
||||||
break;
|
break;
|
||||||
case PlatformType::Web:
|
|
||||||
buildPlatform = BuildPlatform::Web;
|
|
||||||
break;
|
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,7 +106,6 @@ namespace FlaxEditor
|
|||||||
case BuildPlatform.MacOSARM64:
|
case BuildPlatform.MacOSARM64:
|
||||||
case BuildPlatform.MacOSx64: return PlatformType.Mac;
|
case BuildPlatform.MacOSx64: return PlatformType.Mac;
|
||||||
case BuildPlatform.iOSARM64: return PlatformType.iOS;
|
case BuildPlatform.iOSARM64: return PlatformType.iOS;
|
||||||
case BuildPlatform.Web: return PlatformType.Web;
|
|
||||||
default: throw new ArgumentOutOfRangeException(nameof(buildPlatform), buildPlatform, null);
|
default: throw new ArgumentOutOfRangeException(nameof(buildPlatform), buildPlatform, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,7 +138,6 @@ Array<byte> AndroidPlatformTools::SaveCache(CookingData& data, IBuildCache* cach
|
|||||||
result.Add((const byte*)&platformCache, sizeof(platformCache));
|
result.Add((const byte*)&platformCache, sizeof(platformCache));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidPlatformTools::OnBuildStarted(CookingData& data)
|
void AndroidPlatformTools::OnBuildStarted(CookingData& data)
|
||||||
{
|
{
|
||||||
// Adjust the cooking output folder to be located inside the Gradle assets directory
|
// Adjust the cooking output folder to be located inside the Gradle assets directory
|
||||||
@@ -413,6 +412,7 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data)
|
|||||||
}
|
}
|
||||||
LOG(Info, "Output Android APK application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024);
|
LOG(Info, "Output Android APK application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024);
|
||||||
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,157 +0,0 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
||||||
|
|
||||||
#if PLATFORM_TOOLS_WEB
|
|
||||||
|
|
||||||
#include "WebPlatformTools.h"
|
|
||||||
#include "Engine/Platform/File.h"
|
|
||||||
#include "Engine/Platform/FileSystem.h"
|
|
||||||
#include "Engine/Platform/CreateProcessSettings.h"
|
|
||||||
#include "Engine/Platform/Web/WebPlatformSettings.h"
|
|
||||||
#include "Engine/Core/Config/GameSettings.h"
|
|
||||||
#include "Engine/Core/Config/BuildSettings.h"
|
|
||||||
#include "Engine/Content/Content.h"
|
|
||||||
#include "Engine/Content/JsonAsset.h"
|
|
||||||
#include "Engine/Graphics/PixelFormatExtensions.h"
|
|
||||||
#include "Editor/Cooker/GameCooker.h"
|
|
||||||
|
|
||||||
IMPLEMENT_SETTINGS_GETTER(WebPlatformSettings, WebPlatform);
|
|
||||||
|
|
||||||
const Char* WebPlatformTools::GetDisplayName() const
|
|
||||||
{
|
|
||||||
return TEXT("Web");
|
|
||||||
}
|
|
||||||
|
|
||||||
const Char* WebPlatformTools::GetName() const
|
|
||||||
{
|
|
||||||
return TEXT("Web");
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformType WebPlatformTools::GetPlatform() const
|
|
||||||
{
|
|
||||||
return PlatformType::Web;
|
|
||||||
}
|
|
||||||
|
|
||||||
ArchitectureType WebPlatformTools::GetArchitecture() const
|
|
||||||
{
|
|
||||||
return ArchitectureType::x86;
|
|
||||||
}
|
|
||||||
|
|
||||||
DotNetAOTModes WebPlatformTools::UseAOT() const
|
|
||||||
{
|
|
||||||
return DotNetAOTModes::NoDotnet;
|
|
||||||
}
|
|
||||||
|
|
||||||
PixelFormat WebPlatformTools::GetTextureFormat(CookingData& data, TextureBase* texture, PixelFormat format)
|
|
||||||
{
|
|
||||||
// TODO: texture compression for Web (eg. ASTC for mobile and BC for others?)
|
|
||||||
return PixelFormatExtensions::FindUncompressedFormat(format);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WebPlatformTools::IsNativeCodeFile(CookingData& data, const String& file)
|
|
||||||
{
|
|
||||||
String extension = FileSystem::GetExtension(file);
|
|
||||||
return extension.IsEmpty() || extension == TEXT("html") || extension == TEXT("js") || extension == TEXT("wasm");
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebPlatformTools::OnBuildStarted(CookingData& data)
|
|
||||||
{
|
|
||||||
// Adjust the cooking output folder for the data files so file_packager tool can build the and output final data inside the cooker output folder
|
|
||||||
data.DataOutputPath = data.CacheDirectory / TEXT("Files");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WebPlatformTools::OnPostProcess(CookingData& data)
|
|
||||||
{
|
|
||||||
const auto gameSettings = GameSettings::Get();
|
|
||||||
const auto platformSettings = WebPlatformSettings::Get();
|
|
||||||
const auto platformDataPath = data.GetPlatformBinariesRoot();
|
|
||||||
|
|
||||||
// Get name of the output binary (JavaScript and WebAssembly files match)
|
|
||||||
String gameJs;
|
|
||||||
{
|
|
||||||
Array<String> files;
|
|
||||||
FileSystem::DirectoryGetFiles(files, data.OriginalOutputPath, TEXT("*"), DirectorySearchOption::TopDirectoryOnly);
|
|
||||||
for (String& file : files)
|
|
||||||
{
|
|
||||||
if (file.EndsWith(TEXT(".js")))
|
|
||||||
{
|
|
||||||
String outputWasm = String(StringUtils::GetPathWithoutExtension(file)) + TEXT(".wasm");
|
|
||||||
if (files.Contains(outputWasm))
|
|
||||||
{
|
|
||||||
gameJs = file;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (gameJs.IsEmpty())
|
|
||||||
{
|
|
||||||
data.Error(TEXT("Failed to find the main JavaScript for the output game"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pack data files into a single file using Emscripten's file_packager tool
|
|
||||||
{
|
|
||||||
CreateProcessSettings procSettings;
|
|
||||||
String emscriptenSdk = TEXT("EMSDK");
|
|
||||||
Platform::GetEnvironmentVariable(emscriptenSdk, emscriptenSdk);
|
|
||||||
procSettings.FileName = emscriptenSdk / TEXT("upstream/emscripten/tools/file_packager");
|
|
||||||
#if PLATFORM_WIN32
|
|
||||||
procSettings.FileName += TEXT(".bat");
|
|
||||||
#endif
|
|
||||||
procSettings.Arguments = String::Format(TEXT("files.data --preload \"{}@/\" --lz4 --js-output=files.js"), data.DataOutputPath);
|
|
||||||
procSettings.WorkingDirectory = data.OriginalOutputPath;
|
|
||||||
const int32 result = Platform::CreateProcess(procSettings);
|
|
||||||
if (result != 0)
|
|
||||||
{
|
|
||||||
if (!FileSystem::FileExists(procSettings.FileName))
|
|
||||||
data.Error(TEXT("Missing file_packager.bat. Ensure Emscripten SDK installation is valid and 'EMSDK' environment variable points to it."));
|
|
||||||
data.Error(String::Format(TEXT("Failed to package project files (result code: {0}). See log for more info."), result));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: customizable HTML templates
|
|
||||||
|
|
||||||
// Insert packaged file system with game data
|
|
||||||
{
|
|
||||||
String gameJsText;
|
|
||||||
if (File::ReadAllText(gameJs, gameJsText))
|
|
||||||
{
|
|
||||||
data.Error(String::Format(TEXT("Failed to load file '{}'"), gameJs));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
const String filesIncludeBegin = TEXT("// include: files.js");
|
|
||||||
const String filesIncludeEnd = TEXT("// end include: files.js");
|
|
||||||
if (!gameJsText.Contains(filesIncludeBegin))
|
|
||||||
{
|
|
||||||
// Insert generated files.js into the main game file after the minimum_runtime_check.js include
|
|
||||||
String fileJsText;
|
|
||||||
String fileJs = data.OriginalOutputPath / TEXT("files.js");
|
|
||||||
if (File::ReadAllText(fileJs, fileJsText))
|
|
||||||
{
|
|
||||||
data.Error(String::Format(TEXT("Failed to load file '{}'"), fileJs));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
const String insertPrefixLocation = TEXT("// end include: minimum_runtime_check.js");
|
|
||||||
int32 location = gameJsText.Find(insertPrefixLocation);
|
|
||||||
CHECK_RETURN(location != -1, true);
|
|
||||||
location += insertPrefixLocation.Length() + 1;
|
|
||||||
fileJsText = filesIncludeBegin + TEXT("\n") + fileJsText + TEXT("\n") + filesIncludeEnd + TEXT("\n");
|
|
||||||
gameJsText.Insert(location, fileJsText);
|
|
||||||
File::WriteAllText(gameJs, gameJsText, Encoding::UTF8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto buildSettings = BuildSettings::Get();
|
|
||||||
if (buildSettings->SkipPackaging)
|
|
||||||
return false;
|
|
||||||
GameCooker::PackageFiles();
|
|
||||||
|
|
||||||
// TODO: minify/compress output JS files (in Release builds)
|
|
||||||
|
|
||||||
LOG(Info, "Output website size: {0} MB", FileSystem::GetDirectorySize(data.OriginalOutputPath) / 1024 / 1024);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if PLATFORM_TOOLS_WEB
|
|
||||||
|
|
||||||
#include "../../PlatformTools.h"
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Web platform support tools.
|
|
||||||
/// </summary>
|
|
||||||
class WebPlatformTools : public PlatformTools
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// [PlatformTools]
|
|
||||||
const Char* GetDisplayName() const override;
|
|
||||||
const Char* GetName() const override;
|
|
||||||
PlatformType GetPlatform() const override;
|
|
||||||
ArchitectureType GetArchitecture() const override;
|
|
||||||
DotNetAOTModes UseAOT() const override;
|
|
||||||
PixelFormat GetTextureFormat(CookingData& data, TextureBase* texture, PixelFormat format) override;
|
|
||||||
bool IsNativeCodeFile(CookingData& data, const String& file) override;
|
|
||||||
void OnBuildStarted(CookingData& data) override;
|
|
||||||
bool OnPostProcess(CookingData& data) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -572,14 +572,6 @@ bool ProcessShaderBase(CookAssetsStep::AssetCookData& data, ShaderAssetBase* ass
|
|||||||
COMPILE_PROFILE(Vulkan_SM5, SHADER_FILE_CHUNK_INTERNAL_VULKAN_SM5_CACHE);
|
COMPILE_PROFILE(Vulkan_SM5, SHADER_FILE_CHUNK_INTERNAL_VULKAN_SM5_CACHE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#if PLATFORM_TOOLS_WEB
|
|
||||||
case BuildPlatform::Web:
|
|
||||||
{
|
|
||||||
const char* platformDefineName = "PLATFORM_WEB";
|
|
||||||
// TODO: compile shaders for WebGPU
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -39,23 +39,17 @@ bool DeployDataStep::Perform(CookingData& data)
|
|||||||
}
|
}
|
||||||
String dstDotnet = data.DataOutputPath / TEXT("Dotnet");
|
String dstDotnet = data.DataOutputPath / TEXT("Dotnet");
|
||||||
const DotNetAOTModes aotMode = data.Tools->UseAOT();
|
const DotNetAOTModes aotMode = data.Tools->UseAOT();
|
||||||
const bool usAOT = aotMode != DotNetAOTModes::None && aotMode != DotNetAOTModes::NoDotnet;
|
const bool usAOT = aotMode != DotNetAOTModes::None;
|
||||||
if (usAOT)
|
if (usAOT)
|
||||||
{
|
{
|
||||||
// Deploy Dotnet files into intermediate cooking directory for AOT
|
// Deploy Dotnet files into intermediate cooking directory for AOT
|
||||||
FileSystem::DeleteDirectory(dstDotnet);
|
FileSystem::DeleteDirectory(dstDotnet);
|
||||||
dstDotnet = data.ManagedCodeOutputPath;
|
dstDotnet = data.ManagedCodeOutputPath;
|
||||||
}
|
}
|
||||||
if (aotMode == DotNetAOTModes::NoDotnet)
|
if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet())
|
||||||
{
|
|
||||||
// No .NET
|
|
||||||
FileSystem::DeleteDirectory(dstDotnet);
|
|
||||||
}
|
|
||||||
else if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet())
|
|
||||||
{
|
{
|
||||||
// Use system-installed .NET Runtime
|
// Use system-installed .NET Runtime
|
||||||
FileSystem::DeleteDirectory(dstDotnet);
|
FileSystem::DeleteDirectory(dstDotnet);
|
||||||
LOG(Info, "Not using .NET Runtime");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,9 +12,7 @@
|
|||||||
void PrecompileAssembliesStep::OnBuildStarted(CookingData& data)
|
void PrecompileAssembliesStep::OnBuildStarted(CookingData& data)
|
||||||
{
|
{
|
||||||
const DotNetAOTModes aotMode = data.Tools->UseAOT();
|
const DotNetAOTModes aotMode = data.Tools->UseAOT();
|
||||||
if (aotMode == DotNetAOTModes::None ||
|
if (aotMode == DotNetAOTModes::None || EnumHasAllFlags(data.Options, BuildOptions::NoCook))
|
||||||
aotMode == DotNetAOTModes::NoDotnet ||
|
|
||||||
EnumHasAllFlags(data.Options, BuildOptions::NoCook))
|
|
||||||
return;
|
return;
|
||||||
const auto& buildSettings = *BuildSettings::Get();
|
const auto& buildSettings = *BuildSettings::Get();
|
||||||
|
|
||||||
@@ -51,8 +49,7 @@ void PrecompileAssembliesStep::OnBuildStarted(CookingData& data)
|
|||||||
bool PrecompileAssembliesStep::Perform(CookingData& data)
|
bool PrecompileAssembliesStep::Perform(CookingData& data)
|
||||||
{
|
{
|
||||||
const DotNetAOTModes aotMode = data.Tools->UseAOT();
|
const DotNetAOTModes aotMode = data.Tools->UseAOT();
|
||||||
if (aotMode == DotNetAOTModes::None ||
|
if (aotMode == DotNetAOTModes::None)
|
||||||
aotMode == DotNetAOTModes::NoDotnet)
|
|
||||||
return false;
|
return false;
|
||||||
const auto& buildSettings = *BuildSettings::Get();
|
const auto& buildSettings = *BuildSettings::Get();
|
||||||
if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet())
|
if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet())
|
||||||
|
|||||||
@@ -87,7 +87,6 @@ public class Editor : EditorModule
|
|||||||
AddPlatformTools(options, platformToolsRoot, platformToolsRootExternal, "Android", "PLATFORM_TOOLS_ANDROID");
|
AddPlatformTools(options, platformToolsRoot, platformToolsRootExternal, "Android", "PLATFORM_TOOLS_ANDROID");
|
||||||
AddPlatformTools(options, platformToolsRoot, platformToolsRootExternal, "iOS", "PLATFORM_TOOLS_IOS");
|
AddPlatformTools(options, platformToolsRoot, platformToolsRootExternal, "iOS", "PLATFORM_TOOLS_IOS");
|
||||||
}
|
}
|
||||||
AddPlatformTools(options, platformToolsRoot, platformToolsRootExternal, "Web", "PLATFORM_TOOLS_WEB");
|
|
||||||
|
|
||||||
// Visual Studio integration
|
// Visual Studio integration
|
||||||
if (options.Platform.Target == TargetPlatform.Windows && Flax.Build.Platform.BuildTargetPlatform == TargetPlatform.Windows)
|
if (options.Platform.Target == TargetPlatform.Windows && Flax.Build.Platform.BuildTargetPlatform == TargetPlatform.Windows)
|
||||||
|
|||||||
@@ -93,7 +93,6 @@ namespace FlaxEditor.GUI
|
|||||||
new PlatformData(PlatformType.PS5, icons.PS5Icon128, "PlayStation 5"),
|
new PlatformData(PlatformType.PS5, icons.PS5Icon128, "PlayStation 5"),
|
||||||
new PlatformData(PlatformType.Mac, icons.MacOSIcon128, "macOS"),
|
new PlatformData(PlatformType.Mac, icons.MacOSIcon128, "macOS"),
|
||||||
new PlatformData(PlatformType.iOS, icons.IOSIcon128, "iOS"),
|
new PlatformData(PlatformType.iOS, icons.IOSIcon128, "iOS"),
|
||||||
new PlatformData(PlatformType.Web, icons.Flax64, "Web"),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const float IconSize = 64.0f;
|
const float IconSize = 64.0f;
|
||||||
|
|||||||
@@ -201,9 +201,10 @@ namespace FlaxEditor.GUI.Timeline
|
|||||||
var idx = stream.ReadInt32();
|
var idx = stream.ReadInt32();
|
||||||
var id = stream.ReadGuid();
|
var id = stream.ReadGuid();
|
||||||
object value = null;
|
object value = null;
|
||||||
if (version <= 2)
|
if (version == 2)
|
||||||
throw new Exception("Not supported asset version. Open and re-save asset with Flax 1.11.");
|
stream.ReadCommonValue(ref value);
|
||||||
value = stream.ReadVariant();
|
else
|
||||||
|
value = stream.ReadVariant();
|
||||||
|
|
||||||
Emitters[idx].ParametersOverrides.Add(id, value);
|
Emitters[idx].ParametersOverrides.Add(id, value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1603,9 +1603,9 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
Title = "Platform Switch",
|
Title = "Platform Switch",
|
||||||
Description = "Gets the input value based on the runtime-platform type",
|
Description = "Gets the input value based on the runtime-platform type",
|
||||||
Flags = NodeFlags.AllGraphs,
|
Flags = NodeFlags.AllGraphs,
|
||||||
Size = new Float2(220, 260),
|
Size = new Float2(220, 240),
|
||||||
ConnectionsHints = ConnectionsHint.Value,
|
ConnectionsHints = ConnectionsHint.Value,
|
||||||
IndependentBoxes = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
|
IndependentBoxes = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 },
|
||||||
DependentBoxes = new[] { 0 },
|
DependentBoxes = new[] { 0 },
|
||||||
Elements = new[]
|
Elements = new[]
|
||||||
{
|
{
|
||||||
@@ -1622,7 +1622,6 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
NodeElementArchetype.Factory.Input(9, "PlayStation 5", true, null, 10),
|
NodeElementArchetype.Factory.Input(9, "PlayStation 5", true, null, 10),
|
||||||
NodeElementArchetype.Factory.Input(10, "Mac", true, null, 11),
|
NodeElementArchetype.Factory.Input(10, "Mac", true, null, 11),
|
||||||
NodeElementArchetype.Factory.Input(11, "iOS", true, null, 12),
|
NodeElementArchetype.Factory.Input(11, "iOS", true, null, 12),
|
||||||
NodeElementArchetype.Factory.Input(12, "Web", true, null, 13),
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new NodeArchetype
|
new NodeArchetype
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using FlaxEditor.Scripting;
|
||||||
using FlaxEditor.Surface.Elements;
|
using FlaxEditor.Surface.Elements;
|
||||||
using FlaxEditor.Utilities;
|
using FlaxEditor.Utilities;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
@@ -502,8 +503,205 @@ namespace FlaxEditor.Surface
|
|||||||
var tmpHints = _cachedConnections.Value;
|
var tmpHints = _cachedConnections.Value;
|
||||||
var guidBytes = new byte[16];
|
var guidBytes = new byte[16];
|
||||||
if (version < 7000)
|
if (version < 7000)
|
||||||
throw new Exception("Not supported Visject Surface version. Open and re-save asset with Flax 1.11.");
|
{
|
||||||
if (version == 7000)
|
// Time saved (not used anymore to prevent binary diffs after saving unmodified surface)
|
||||||
|
stream.ReadInt64();
|
||||||
|
|
||||||
|
// Nodes count
|
||||||
|
int nodesCount = stream.ReadInt32();
|
||||||
|
if (Nodes.Capacity < nodesCount)
|
||||||
|
Nodes.Capacity = nodesCount;
|
||||||
|
tmpHints.Clear();
|
||||||
|
tmpHints.Capacity = Mathf.Max(tmpHints.Capacity, nodesCount * 4);
|
||||||
|
|
||||||
|
// Parameters count
|
||||||
|
int parametersCount = stream.ReadInt32();
|
||||||
|
if (Parameters.Capacity < parametersCount)
|
||||||
|
Parameters.Capacity = parametersCount;
|
||||||
|
|
||||||
|
// For each node
|
||||||
|
for (int i = 0; i < nodesCount; i++)
|
||||||
|
{
|
||||||
|
// ID
|
||||||
|
uint id = stream.ReadUInt32();
|
||||||
|
|
||||||
|
// Type
|
||||||
|
ushort typeId = stream.ReadUInt16();
|
||||||
|
ushort groupId = stream.ReadUInt16();
|
||||||
|
|
||||||
|
// Create node
|
||||||
|
SurfaceNode node;
|
||||||
|
if (groupId == Archetypes.Custom.GroupID)
|
||||||
|
node = new DummyCustomNode(id, this);
|
||||||
|
else
|
||||||
|
node = NodeFactory.CreateNode(nodeArchetypes, id, this, groupId, typeId);
|
||||||
|
if (node == null)
|
||||||
|
node = new MissingNode(id, this, groupId, typeId);
|
||||||
|
Nodes.Add(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For each param
|
||||||
|
for (int i = 0; i < parametersCount; i++)
|
||||||
|
{
|
||||||
|
// Create param
|
||||||
|
var param = new SurfaceParameter();
|
||||||
|
Parameters.Add(param);
|
||||||
|
|
||||||
|
// Properties
|
||||||
|
param.Type = new ScriptType(GetGraphParameterValueType((GraphParamType_Deprecated)stream.ReadByte()));
|
||||||
|
stream.Read(guidBytes, 0, 16);
|
||||||
|
param.ID = new Guid(guidBytes);
|
||||||
|
param.Name = stream.ReadStr(97);
|
||||||
|
param.IsPublic = stream.ReadByte() != 0;
|
||||||
|
bool isStatic = stream.ReadByte() != 0;
|
||||||
|
bool isUIVisible = stream.ReadByte() != 0;
|
||||||
|
bool isUIEditable = stream.ReadByte() != 0;
|
||||||
|
|
||||||
|
// References [Deprecated]
|
||||||
|
int refsCount = stream.ReadInt32();
|
||||||
|
for (int j = 0; j < refsCount; j++)
|
||||||
|
{
|
||||||
|
uint refID = stream.ReadUInt32();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value
|
||||||
|
stream.ReadCommonValue(ref param.Value);
|
||||||
|
|
||||||
|
// Meta
|
||||||
|
param.Meta.Load(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For each node
|
||||||
|
for (int i = 0; i < nodesCount; i++)
|
||||||
|
{
|
||||||
|
var node = Nodes[i];
|
||||||
|
|
||||||
|
int valuesCnt = stream.ReadInt32();
|
||||||
|
int firstValueReadIdx = 0;
|
||||||
|
|
||||||
|
// Special case for missing nodes
|
||||||
|
if (node is DummyCustomNode customNode)
|
||||||
|
{
|
||||||
|
node = null;
|
||||||
|
|
||||||
|
// Values check
|
||||||
|
if (valuesCnt < 2)
|
||||||
|
throw new Exception("Missing custom nodes data.");
|
||||||
|
|
||||||
|
// Node typename check
|
||||||
|
object typeNameValue = null;
|
||||||
|
stream.ReadCommonValue(ref typeNameValue);
|
||||||
|
firstValueReadIdx = 1;
|
||||||
|
string typeName = typeNameValue as string ?? string.Empty;
|
||||||
|
|
||||||
|
// Find custom node archetype that matches this node type (it must be unique)
|
||||||
|
if (customNodes?.Archetypes != null && typeName.Length != 0)
|
||||||
|
{
|
||||||
|
NodeArchetype arch = null;
|
||||||
|
foreach (var nodeArchetype in customNodes.Archetypes)
|
||||||
|
{
|
||||||
|
if (string.Equals(Archetypes.Custom.GetNodeTypeName(nodeArchetype), typeName, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
arch = nodeArchetype;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (arch != null)
|
||||||
|
node = NodeFactory.CreateNode(customNode.ID, this, customNodes, arch);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to the
|
||||||
|
if (node == null)
|
||||||
|
{
|
||||||
|
Editor.LogWarning(string.Format("Cannot find custom node archetype for {0}", typeName));
|
||||||
|
node = new MissingNode(customNode.ID, this, Archetypes.Custom.GroupID, customNode.Archetype.TypeID);
|
||||||
|
}
|
||||||
|
Nodes[i] = node;
|
||||||
|
|
||||||
|
// Store node typename in values container
|
||||||
|
node.Values[0] = typeName;
|
||||||
|
}
|
||||||
|
if (node is MissingNode)
|
||||||
|
{
|
||||||
|
// Read all values
|
||||||
|
Array.Resize(ref node.Values, valuesCnt);
|
||||||
|
for (int j = firstValueReadIdx; j < valuesCnt; j++)
|
||||||
|
{
|
||||||
|
// ReSharper disable once PossibleNullReferenceException
|
||||||
|
stream.ReadCommonValue(ref node.Values[j]);
|
||||||
|
}
|
||||||
|
firstValueReadIdx = valuesCnt = node.Values.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Values
|
||||||
|
int nodeValuesCnt = node.Values?.Length ?? 0;
|
||||||
|
if (valuesCnt == nodeValuesCnt)
|
||||||
|
{
|
||||||
|
for (int j = firstValueReadIdx; j < valuesCnt; j++)
|
||||||
|
{
|
||||||
|
// ReSharper disable once PossibleNullReferenceException
|
||||||
|
stream.ReadCommonValue(ref node.Values[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((node.Archetype.Flags & NodeFlags.VariableValuesSize) != 0)
|
||||||
|
{
|
||||||
|
node.Values = new object[valuesCnt];
|
||||||
|
for (int j = firstValueReadIdx; j < valuesCnt; j++)
|
||||||
|
{
|
||||||
|
// ReSharper disable once PossibleNullReferenceException
|
||||||
|
stream.ReadCommonValue(ref node.Values[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Editor.LogWarning(string.Format("Invalid node values. Loaded: {0}, expected: {1}. Type: {2}, {3}", valuesCnt, nodeValuesCnt, node.Archetype.Title, node.Archetype.TypeID));
|
||||||
|
|
||||||
|
object dummy = null;
|
||||||
|
for (int j = firstValueReadIdx; j < valuesCnt; j++)
|
||||||
|
{
|
||||||
|
stream.ReadCommonValue(ref dummy);
|
||||||
|
|
||||||
|
if (j < nodeValuesCnt &&
|
||||||
|
dummy != null &&
|
||||||
|
node.Values[j] != null &&
|
||||||
|
node.Values[j].GetType() == dummy.GetType())
|
||||||
|
{
|
||||||
|
node.Values[j] = dummy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Boxes
|
||||||
|
ushort boxesCount = stream.ReadUInt16();
|
||||||
|
for (int j = 0; j < boxesCount; j++)
|
||||||
|
{
|
||||||
|
var id = stream.ReadByte();
|
||||||
|
stream.ReadUInt32(); // Skip type
|
||||||
|
ushort connectionsCnt = stream.ReadUInt16();
|
||||||
|
|
||||||
|
ConnectionHint hint;
|
||||||
|
hint.NodeB = node.ID;
|
||||||
|
hint.BoxB = id;
|
||||||
|
|
||||||
|
for (int k = 0; k < connectionsCnt; k++)
|
||||||
|
{
|
||||||
|
uint targetNodeID = stream.ReadUInt32();
|
||||||
|
byte targetBoxID = stream.ReadByte();
|
||||||
|
|
||||||
|
hint.NodeA = targetNodeID;
|
||||||
|
hint.BoxA = targetBoxID;
|
||||||
|
|
||||||
|
tmpHints.Add(hint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Meta
|
||||||
|
node.Meta.Load(stream);
|
||||||
|
|
||||||
|
OnControlLoaded(node, SurfaceNodeActions.Load);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (version == 7000)
|
||||||
{
|
{
|
||||||
// Nodes count
|
// Nodes count
|
||||||
int nodesCount = stream.ReadInt32();
|
int nodesCount = stream.ReadInt32();
|
||||||
|
|||||||
@@ -667,6 +667,310 @@ namespace FlaxEditor.Utilities
|
|||||||
stream.Write(value.Size.Y);
|
stream.Write(value.Size.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static void ReadCommonValue(this BinaryReader stream, ref object value)
|
||||||
|
{
|
||||||
|
byte type = stream.ReadByte();
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case 0: // CommonType::Bool:
|
||||||
|
value = stream.ReadByte() != 0;
|
||||||
|
break;
|
||||||
|
case 1: // CommonType::Integer:
|
||||||
|
{
|
||||||
|
value = stream.ReadInt32();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: // CommonType::Float:
|
||||||
|
{
|
||||||
|
value = stream.ReadSingle();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3: // CommonType::Vector2:
|
||||||
|
{
|
||||||
|
value = stream.ReadFloat2();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4: // CommonType::Vector3:
|
||||||
|
{
|
||||||
|
value = stream.ReadFloat3();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 5: // CommonType::Vector4:
|
||||||
|
{
|
||||||
|
value = stream.ReadFloat4();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 6: // CommonType::Color:
|
||||||
|
{
|
||||||
|
value = stream.ReadColor();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 7: // CommonType::Guid:
|
||||||
|
{
|
||||||
|
value = stream.ReadGuid();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 8: // CommonType::String:
|
||||||
|
{
|
||||||
|
int length = stream.ReadInt32();
|
||||||
|
if (length <= 0)
|
||||||
|
{
|
||||||
|
value = string.Empty;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var data = new char[length];
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
var c = stream.ReadUInt16();
|
||||||
|
data[i] = (char)(c ^ 953);
|
||||||
|
}
|
||||||
|
value = new string(data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 9: // CommonType::Box:
|
||||||
|
{
|
||||||
|
value = new BoundingBox(new Vector3(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()),
|
||||||
|
new Vector3(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 10: // CommonType::Rotation:
|
||||||
|
{
|
||||||
|
value = stream.ReadQuaternion();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 11: // CommonType::Transform:
|
||||||
|
{
|
||||||
|
value = new Transform(new Vector3(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()),
|
||||||
|
new Quaternion(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()),
|
||||||
|
new Float3(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 12: // CommonType::Sphere:
|
||||||
|
{
|
||||||
|
value = new BoundingSphere(new Vector3(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()),
|
||||||
|
stream.ReadSingle());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 13: // CommonType::Rect:
|
||||||
|
{
|
||||||
|
value = new Rectangle(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 15: // CommonType::Matrix
|
||||||
|
{
|
||||||
|
value = new Matrix(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(),
|
||||||
|
stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(),
|
||||||
|
stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(),
|
||||||
|
stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 16: // CommonType::Blob
|
||||||
|
{
|
||||||
|
int length = stream.ReadInt32();
|
||||||
|
value = stream.ReadBytes(length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 18: // CommonType::Ray
|
||||||
|
{
|
||||||
|
value = new Ray(new Vector3(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()),
|
||||||
|
new Vector3(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 19: // CommonType::Int2
|
||||||
|
{
|
||||||
|
value = stream.ReadInt2();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 20: // CommonType::Int3
|
||||||
|
{
|
||||||
|
value = stream.ReadInt3();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 21: // CommonType::Int4
|
||||||
|
{
|
||||||
|
value = stream.ReadInt4();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: throw new SystemException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void WriteCommonValue(this BinaryWriter stream, object value)
|
||||||
|
{
|
||||||
|
if (value is bool asBool)
|
||||||
|
{
|
||||||
|
stream.Write((byte)0);
|
||||||
|
stream.Write((byte)(asBool ? 1 : 0));
|
||||||
|
}
|
||||||
|
else if (value is int asInt)
|
||||||
|
{
|
||||||
|
stream.Write((byte)1);
|
||||||
|
stream.Write(asInt);
|
||||||
|
}
|
||||||
|
else if (value is long asLong)
|
||||||
|
{
|
||||||
|
stream.Write((byte)1);
|
||||||
|
stream.Write((int)asLong);
|
||||||
|
}
|
||||||
|
else if (value is float asFloat)
|
||||||
|
{
|
||||||
|
stream.Write((byte)2);
|
||||||
|
stream.Write(asFloat);
|
||||||
|
}
|
||||||
|
else if (value is double asDouble)
|
||||||
|
{
|
||||||
|
stream.Write((byte)2);
|
||||||
|
stream.Write((float)asDouble);
|
||||||
|
}
|
||||||
|
else if (value is Vector2 asVector2)
|
||||||
|
{
|
||||||
|
stream.Write((byte)3);
|
||||||
|
stream.Write((float)asVector2.X);
|
||||||
|
stream.Write((float)asVector2.Y);
|
||||||
|
}
|
||||||
|
else if (value is Vector3 asVector3)
|
||||||
|
{
|
||||||
|
stream.Write((byte)4);
|
||||||
|
stream.Write((float)asVector3.X);
|
||||||
|
stream.Write((float)asVector3.Y);
|
||||||
|
stream.Write((float)asVector3.Z);
|
||||||
|
}
|
||||||
|
else if (value is Vector4 asVector4)
|
||||||
|
{
|
||||||
|
stream.Write((byte)5);
|
||||||
|
stream.Write((float)asVector4.X);
|
||||||
|
stream.Write((float)asVector4.Y);
|
||||||
|
stream.Write((float)asVector4.Z);
|
||||||
|
stream.Write((float)asVector4.W);
|
||||||
|
}
|
||||||
|
else if (value is Color asColor)
|
||||||
|
{
|
||||||
|
stream.Write((byte)6);
|
||||||
|
stream.Write(asColor.R);
|
||||||
|
stream.Write(asColor.G);
|
||||||
|
stream.Write(asColor.B);
|
||||||
|
stream.Write(asColor.A);
|
||||||
|
}
|
||||||
|
else if (value is Guid asGuid)
|
||||||
|
{
|
||||||
|
stream.Write((byte)7);
|
||||||
|
stream.WriteGuid(ref asGuid);
|
||||||
|
}
|
||||||
|
else if (value is string asString)
|
||||||
|
{
|
||||||
|
stream.Write((byte)8);
|
||||||
|
stream.Write(asString.Length);
|
||||||
|
for (int i = 0; i < asString.Length; i++)
|
||||||
|
stream.Write((ushort)(asString[i] ^ -14));
|
||||||
|
}
|
||||||
|
else if (value is BoundingBox asBox)
|
||||||
|
{
|
||||||
|
stream.Write((byte)9);
|
||||||
|
stream.Write((float)asBox.Minimum.X);
|
||||||
|
stream.Write((float)asBox.Minimum.Y);
|
||||||
|
stream.Write((float)asBox.Minimum.Z);
|
||||||
|
stream.Write((float)asBox.Maximum.X);
|
||||||
|
stream.Write((float)asBox.Maximum.Y);
|
||||||
|
stream.Write((float)asBox.Maximum.Z);
|
||||||
|
}
|
||||||
|
else if (value is Quaternion asRotation)
|
||||||
|
{
|
||||||
|
stream.Write((byte)10);
|
||||||
|
stream.Write(asRotation.X);
|
||||||
|
stream.Write(asRotation.Y);
|
||||||
|
stream.Write(asRotation.Z);
|
||||||
|
stream.Write(asRotation.X);
|
||||||
|
}
|
||||||
|
else if (value is Transform asTransform)
|
||||||
|
{
|
||||||
|
stream.Write((byte)11);
|
||||||
|
stream.Write((float)asTransform.Translation.X);
|
||||||
|
stream.Write((float)asTransform.Translation.Y);
|
||||||
|
stream.Write((float)asTransform.Translation.Z);
|
||||||
|
stream.Write(asTransform.Orientation.X);
|
||||||
|
stream.Write(asTransform.Orientation.Y);
|
||||||
|
stream.Write(asTransform.Orientation.Z);
|
||||||
|
stream.Write(asTransform.Orientation.X);
|
||||||
|
stream.Write(asTransform.Scale.X);
|
||||||
|
stream.Write(asTransform.Scale.Y);
|
||||||
|
stream.Write(asTransform.Scale.Z);
|
||||||
|
}
|
||||||
|
else if (value is BoundingSphere asSphere)
|
||||||
|
{
|
||||||
|
stream.Write((byte)12);
|
||||||
|
stream.Write((float)asSphere.Center.X);
|
||||||
|
stream.Write((float)asSphere.Center.Y);
|
||||||
|
stream.Write((float)asSphere.Center.Z);
|
||||||
|
stream.Write((float)asSphere.Radius);
|
||||||
|
}
|
||||||
|
else if (value is Rectangle asRect)
|
||||||
|
{
|
||||||
|
stream.Write((byte)13);
|
||||||
|
stream.Write(asRect.Location.X);
|
||||||
|
stream.Write(asRect.Location.Y);
|
||||||
|
stream.Write(asRect.Size.X);
|
||||||
|
stream.Write(asRect.Size.Y);
|
||||||
|
}
|
||||||
|
else if (value is Matrix asMatrix)
|
||||||
|
{
|
||||||
|
stream.Write((byte)15);
|
||||||
|
stream.Write(asMatrix.M11);
|
||||||
|
stream.Write(asMatrix.M12);
|
||||||
|
stream.Write(asMatrix.M13);
|
||||||
|
stream.Write(asMatrix.M14);
|
||||||
|
stream.Write(asMatrix.M21);
|
||||||
|
stream.Write(asMatrix.M22);
|
||||||
|
stream.Write(asMatrix.M23);
|
||||||
|
stream.Write(asMatrix.M24);
|
||||||
|
stream.Write(asMatrix.M31);
|
||||||
|
stream.Write(asMatrix.M32);
|
||||||
|
stream.Write(asMatrix.M33);
|
||||||
|
stream.Write(asMatrix.M34);
|
||||||
|
stream.Write(asMatrix.M41);
|
||||||
|
stream.Write(asMatrix.M42);
|
||||||
|
stream.Write(asMatrix.M43);
|
||||||
|
stream.Write(asMatrix.M44);
|
||||||
|
}
|
||||||
|
else if (value is byte[] asBlob)
|
||||||
|
{
|
||||||
|
stream.Write((byte)16);
|
||||||
|
stream.Write(asBlob.Length);
|
||||||
|
stream.Write(asBlob);
|
||||||
|
}
|
||||||
|
else if (value is Ray asRay)
|
||||||
|
{
|
||||||
|
stream.Write((byte)18);
|
||||||
|
stream.Write((float)asRay.Position.X);
|
||||||
|
stream.Write((float)asRay.Position.Y);
|
||||||
|
stream.Write((float)asRay.Position.Z);
|
||||||
|
stream.Write((float)asRay.Direction.X);
|
||||||
|
stream.Write((float)asRay.Direction.Y);
|
||||||
|
stream.Write((float)asRay.Direction.Z);
|
||||||
|
}
|
||||||
|
else if (value is Int2 asInt2)
|
||||||
|
{
|
||||||
|
stream.Write((byte)19);
|
||||||
|
stream.Write(asInt2);
|
||||||
|
}
|
||||||
|
else if (value is Int3 asInt3)
|
||||||
|
{
|
||||||
|
stream.Write((byte)20);
|
||||||
|
stream.Write(asInt3);
|
||||||
|
}
|
||||||
|
else if (value is Int4 asInt4)
|
||||||
|
{
|
||||||
|
stream.Write((byte)21);
|
||||||
|
stream.Write(asInt4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NotSupportedException(string.Format("Invalid Common Value type {0}", value != null ? value.GetType().ToString() : "null"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Shows the source code window.
|
/// Shows the source code window.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ namespace FlaxEditor.Windows
|
|||||||
{ PlatformType.PS5, new PS5() },
|
{ PlatformType.PS5, new PS5() },
|
||||||
{ PlatformType.Mac, new Mac() },
|
{ PlatformType.Mac, new Mac() },
|
||||||
{ PlatformType.iOS, new iOS() },
|
{ PlatformType.iOS, new iOS() },
|
||||||
{ PlatformType.Web, new Web() },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public BuildTabProxy(GameCookerWindow win, PlatformSelector platformSelector)
|
public BuildTabProxy(GameCookerWindow win, PlatformSelector platformSelector)
|
||||||
@@ -166,7 +165,6 @@ namespace FlaxEditor.Windows
|
|||||||
case BuildPlatform.UWPx64:
|
case BuildPlatform.UWPx64:
|
||||||
case BuildPlatform.LinuxX64:
|
case BuildPlatform.LinuxX64:
|
||||||
case BuildPlatform.AndroidARM64:
|
case BuildPlatform.AndroidARM64:
|
||||||
case BuildPlatform.Web:
|
|
||||||
text += "\nUse Flax Launcher and download the required package.";
|
text += "\nUse Flax Launcher and download the required package.";
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
@@ -540,11 +538,6 @@ namespace FlaxEditor.Windows
|
|||||||
protected override BuildPlatform BuildPlatform => BuildPlatform.iOSARM64;
|
protected override BuildPlatform BuildPlatform => BuildPlatform.iOSARM64;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Web : Platform
|
|
||||||
{
|
|
||||||
protected override BuildPlatform BuildPlatform => BuildPlatform.Web;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Editor : CustomEditor
|
class Editor : CustomEditor
|
||||||
{
|
{
|
||||||
private PlatformType _platform;
|
private PlatformType _platform;
|
||||||
@@ -599,9 +592,6 @@ namespace FlaxEditor.Windows
|
|||||||
case PlatformType.iOS:
|
case PlatformType.iOS:
|
||||||
name = "iOS";
|
name = "iOS";
|
||||||
break;
|
break;
|
||||||
case PlatformType.Web:
|
|
||||||
name = "Web";
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
name = Utilities.Utils.GetPropertyNameUI(_platform.ToString());
|
name = Utilities.Utils.GetPropertyNameUI(_platform.ToString());
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -60,9 +60,6 @@ public class Audio : EngineModule
|
|||||||
case TargetPlatform.iOS:
|
case TargetPlatform.iOS:
|
||||||
useOpenAL = true;
|
useOpenAL = true;
|
||||||
break;
|
break;
|
||||||
case TargetPlatform.Web:
|
|
||||||
// TODO: audio playback on Web (OpenAL)
|
|
||||||
break;
|
|
||||||
default: throw new InvalidPlatformException(options.Platform.Target);
|
default: throw new InvalidPlatformException(options.Platform.Target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -194,7 +194,6 @@ bool AudioClip::ExtractData(Array<byte>& resultData, AudioDataInfo& resultDataIn
|
|||||||
|
|
||||||
bool AudioClip::ExtractDataFloat(Array<float>& resultData, AudioDataInfo& resultDataInfo)
|
bool AudioClip::ExtractDataFloat(Array<float>& resultData, AudioDataInfo& resultDataInfo)
|
||||||
{
|
{
|
||||||
#if COMPILE_WITH_AUDIO_TOOL
|
|
||||||
// Extract PCM data
|
// Extract PCM data
|
||||||
Array<byte> data;
|
Array<byte> data;
|
||||||
if (ExtractDataRaw(data, resultDataInfo))
|
if (ExtractDataRaw(data, resultDataInfo))
|
||||||
@@ -206,9 +205,6 @@ bool AudioClip::ExtractDataFloat(Array<float>& resultData, AudioDataInfo& result
|
|||||||
resultDataInfo.BitDepth = 32;
|
resultDataInfo.BitDepth = 32;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
#else
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioClip::ExtractDataRaw(Array<byte>& resultData, AudioDataInfo& resultDataInfo)
|
bool AudioClip::ExtractDataRaw(Array<byte>& resultData, AudioDataInfo& resultDataInfo)
|
||||||
@@ -479,7 +475,6 @@ bool AudioClip::WriteBuffer(int32 chunkIndex)
|
|||||||
}
|
}
|
||||||
info.NumSamples = Math::AlignDown(data.Length() / bytesPerSample, info.NumChannels * bytesPerSample);
|
info.NumSamples = Math::AlignDown(data.Length() / bytesPerSample, info.NumChannels * bytesPerSample);
|
||||||
|
|
||||||
#if COMPILE_WITH_AUDIO_TOOL
|
|
||||||
// Convert to Mono if used as 3D source and backend doesn't support it
|
// Convert to Mono if used as 3D source and backend doesn't support it
|
||||||
if (Is3D() && info.NumChannels > 1 && EnumHasNoneFlags(AudioBackend::Features(), AudioBackend::FeatureFlags::SpatialMultiChannel))
|
if (Is3D() && info.NumChannels > 1 && EnumHasNoneFlags(AudioBackend::Features(), AudioBackend::FeatureFlags::SpatialMultiChannel))
|
||||||
{
|
{
|
||||||
@@ -491,7 +486,6 @@ bool AudioClip::WriteBuffer(int32 chunkIndex)
|
|||||||
info.NumSamples = samplesPerChannel;
|
info.NumSamples = samplesPerChannel;
|
||||||
data = Span<byte>(tmp2.Get(), tmp2.Count());
|
data = Span<byte>(tmp2.Get(), tmp2.Count());
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Write samples to the audio buffer (create one if missing)
|
// Write samples to the audio buffer (create one if missing)
|
||||||
Locker.Lock(); // StreamingTask loads buffers without lock so do it here
|
Locker.Lock(); // StreamingTask loads buffers without lock so do it here
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include "Material.h"
|
#include "Material.h"
|
||||||
#include "Engine/Core/Log.h"
|
#include "Engine/Core/Log.h"
|
||||||
#include "Engine/Core/Types/DataContainer.h"
|
#include "Engine/Core/Types/DataContainer.h"
|
||||||
#include "Engine/Content/Deprecated.h"
|
|
||||||
#include "Engine/Content/Upgraders/ShaderAssetUpgrader.h"
|
#include "Engine/Content/Upgraders/ShaderAssetUpgrader.h"
|
||||||
#include "Engine/Content/Factories/BinaryAssetFactory.h"
|
#include "Engine/Content/Factories/BinaryAssetFactory.h"
|
||||||
#include "Engine/Graphics/GPUDevice.h"
|
#include "Engine/Graphics/GPUDevice.h"
|
||||||
|
|||||||
@@ -80,14 +80,10 @@ namespace
|
|||||||
// Loading assets
|
// Loading assets
|
||||||
THREADLOCAL LoadingThread* ThisLoadThread = nullptr;
|
THREADLOCAL LoadingThread* ThisLoadThread = nullptr;
|
||||||
LoadingThread* MainLoadThread = nullptr;
|
LoadingThread* MainLoadThread = nullptr;
|
||||||
#if PLATFORM_THREADS_LIMIT > 1
|
|
||||||
Array<LoadingThread*> LoadThreads;
|
Array<LoadingThread*> LoadThreads;
|
||||||
ConcurrentTaskQueue<ContentLoadTask> LoadTasks;
|
ConcurrentTaskQueue<ContentLoadTask> LoadTasks;
|
||||||
ConditionVariable LoadTasksSignal;
|
ConditionVariable LoadTasksSignal;
|
||||||
CriticalSection LoadTasksMutex;
|
CriticalSection LoadTasksMutex;
|
||||||
#else
|
|
||||||
Array<ContentLoadTask*> LoadTasks;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Unloading assets
|
// Unloading assets
|
||||||
Dictionary<Asset*, TimeSpan> UnloadQueue;
|
Dictionary<Asset*, TimeSpan> UnloadQueue;
|
||||||
@@ -129,12 +125,11 @@ bool ContentService::Init()
|
|||||||
Cache.Init();
|
Cache.Init();
|
||||||
|
|
||||||
// Create loading threads
|
// Create loading threads
|
||||||
MainLoadThread = New<LoadingThread>();
|
|
||||||
ThisLoadThread = MainLoadThread;
|
|
||||||
#if PLATFORM_THREADS_LIMIT > 1
|
|
||||||
const CPUInfo cpuInfo = Platform::GetCPUInfo();
|
const CPUInfo cpuInfo = Platform::GetCPUInfo();
|
||||||
const int32 count = Math::Clamp(Math::CeilToInt(LOADING_THREAD_PER_LOGICAL_CORE * (float)cpuInfo.LogicalProcessorCount), 1, 12);
|
const int32 count = Math::Clamp(Math::CeilToInt(LOADING_THREAD_PER_LOGICAL_CORE * (float)cpuInfo.LogicalProcessorCount), 1, 12);
|
||||||
LOG(Info, "Creating {0} content loading threads...", count);
|
LOG(Info, "Creating {0} content loading threads...", count);
|
||||||
|
MainLoadThread = New<LoadingThread>();
|
||||||
|
ThisLoadThread = MainLoadThread;
|
||||||
LoadThreads.Resize(count);
|
LoadThreads.Resize(count);
|
||||||
for (int32 i = 0; i < count; i++)
|
for (int32 i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
@@ -147,7 +142,6 @@ bool ContentService::Init()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -156,29 +150,14 @@ void ContentService::Update()
|
|||||||
{
|
{
|
||||||
PROFILE_CPU();
|
PROFILE_CPU();
|
||||||
|
|
||||||
#if PLATFORM_THREADS_LIMIT == 1
|
ScopeLock lock(LoadedAssetsToInvokeLocker);
|
||||||
// Run content-streaming tasks on a main thread
|
|
||||||
if (LoadTasks.HasItems())
|
|
||||||
{
|
|
||||||
double timeLimit = 0.01; // 10ms
|
|
||||||
double startTime = Platform::GetTimeSeconds();
|
|
||||||
do
|
|
||||||
{
|
|
||||||
auto task = LoadTasks[0];
|
|
||||||
LoadTasks.RemoveAt(0);
|
|
||||||
MainLoadThread->Run(task);
|
|
||||||
} while (LoadTasks.HasItems() && Platform::GetTimeSeconds() - startTime < timeLimit);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Broadcast `OnLoaded` events
|
// Broadcast `OnLoaded` events
|
||||||
LoadedAssetsToInvokeLocker.Lock();
|
|
||||||
while (LoadedAssetsToInvoke.HasItems())
|
while (LoadedAssetsToInvoke.HasItems())
|
||||||
{
|
{
|
||||||
auto asset = LoadedAssetsToInvoke.Dequeue();
|
auto asset = LoadedAssetsToInvoke.Dequeue();
|
||||||
asset->onLoaded_MainThread();
|
asset->onLoaded_MainThread();
|
||||||
}
|
}
|
||||||
LoadedAssetsToInvokeLocker.Unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentService::LateUpdate()
|
void ContentService::LateUpdate()
|
||||||
@@ -240,12 +219,10 @@ void ContentService::LateUpdate()
|
|||||||
|
|
||||||
void ContentService::BeforeExit()
|
void ContentService::BeforeExit()
|
||||||
{
|
{
|
||||||
#if PLATFORM_THREADS_LIMIT > 1
|
|
||||||
// Signal threads to end work soon
|
// Signal threads to end work soon
|
||||||
for (auto thread : LoadThreads)
|
for (auto thread : LoadThreads)
|
||||||
thread->NotifyExit();
|
thread->NotifyExit();
|
||||||
LoadTasksSignal.NotifyAll();
|
LoadTasksSignal.NotifyAll();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentService::Dispose()
|
void ContentService::Dispose()
|
||||||
@@ -274,7 +251,6 @@ void ContentService::Dispose()
|
|||||||
// NOW dispose graphics device - where there is no loaded assets at all
|
// NOW dispose graphics device - where there is no loaded assets at all
|
||||||
Graphics::DisposeDevice();
|
Graphics::DisposeDevice();
|
||||||
|
|
||||||
#if PLATFORM_THREADS_LIMIT > 1
|
|
||||||
// Exit all load threads
|
// Exit all load threads
|
||||||
for (auto thread : LoadThreads)
|
for (auto thread : LoadThreads)
|
||||||
thread->NotifyExit();
|
thread->NotifyExit();
|
||||||
@@ -282,19 +258,12 @@ void ContentService::Dispose()
|
|||||||
for (auto thread : LoadThreads)
|
for (auto thread : LoadThreads)
|
||||||
thread->Join();
|
thread->Join();
|
||||||
LoadThreads.ClearDelete();
|
LoadThreads.ClearDelete();
|
||||||
#endif
|
|
||||||
Delete(MainLoadThread);
|
Delete(MainLoadThread);
|
||||||
MainLoadThread = nullptr;
|
MainLoadThread = nullptr;
|
||||||
ThisLoadThread = nullptr;
|
ThisLoadThread = nullptr;
|
||||||
|
|
||||||
#if PLATFORM_THREADS_LIMIT > 1
|
|
||||||
// Cancel all remaining tasks (no chance to execute them)
|
// Cancel all remaining tasks (no chance to execute them)
|
||||||
LoadTasks.CancelAll();
|
LoadTasks.CancelAll();
|
||||||
#else
|
|
||||||
for (auto* e : LoadTasks)
|
|
||||||
e->Cancel();
|
|
||||||
LoadTasks.Clear();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IAssetFactory::Collection& IAssetFactory::Get()
|
IAssetFactory::Collection& IAssetFactory::Get()
|
||||||
@@ -360,7 +329,6 @@ String LoadingThread::ToString() const
|
|||||||
|
|
||||||
int32 LoadingThread::Run()
|
int32 LoadingThread::Run()
|
||||||
{
|
{
|
||||||
#if PLATFORM_THREADS_LIMIT > 1
|
|
||||||
PROFILE_MEM(Content);
|
PROFILE_MEM(Content);
|
||||||
#if USE_EDITOR && PLATFORM_WINDOWS
|
#if USE_EDITOR && PLATFORM_WINDOWS
|
||||||
// Initialize COM
|
// Initialize COM
|
||||||
@@ -398,7 +366,6 @@ int32 LoadingThread::Run()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ThisLoadThread = nullptr;
|
ThisLoadThread = nullptr;
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,9 +382,7 @@ String ContentLoadTask::ToString() const
|
|||||||
void ContentLoadTask::Enqueue()
|
void ContentLoadTask::Enqueue()
|
||||||
{
|
{
|
||||||
LoadTasks.Add(this);
|
LoadTasks.Add(this);
|
||||||
#if PLATFORM_THREADS_LIMIT > 1
|
|
||||||
LoadTasksSignal.NotifyOne();
|
LoadTasksSignal.NotifyOne();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ContentLoadTask::Run()
|
bool ContentLoadTask::Run()
|
||||||
@@ -1172,7 +1137,6 @@ void Content::WaitForTask(ContentLoadTask* loadingTask, double timeoutInMillisec
|
|||||||
#define CHECK_CONDITIONS() (!Engine::ShouldExit() && (timeoutInSeconds <= 0.0 || Platform::GetTimeSeconds() - startTime < timeoutInSeconds))
|
#define CHECK_CONDITIONS() (!Engine::ShouldExit() && (timeoutInSeconds <= 0.0 || Platform::GetTimeSeconds() - startTime < timeoutInSeconds))
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
#if PLATFORM_THREADS_LIMIT > 1
|
|
||||||
// Give opportunity for other threads to use the current core
|
// Give opportunity for other threads to use the current core
|
||||||
if (loopCounter == 0)
|
if (loopCounter == 0)
|
||||||
; // First run is fast
|
; // First run is fast
|
||||||
@@ -1219,34 +1183,6 @@ void Content::WaitForTask(ContentLoadTask* loadingTask, double timeoutInMillisec
|
|||||||
LoadTasks.enqueue_bulk(localQueue.Get(), localQueue.Count());
|
LoadTasks.enqueue_bulk(localQueue.Get(), localQueue.Count());
|
||||||
localQueue.Clear();
|
localQueue.Clear();
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
// Try to execute content tasks
|
|
||||||
if (task->IsQueued() && CHECK_CONDITIONS() && !LoadTasks.Remove((ContentLoadTask*)task))
|
|
||||||
{
|
|
||||||
PROFILE_CPU_NAMED("Inline");
|
|
||||||
ZoneColor(0xffaaaaaa);
|
|
||||||
thread->Run((ContentLoadTask*)task);
|
|
||||||
}
|
|
||||||
while (!task->IsQueued() && CHECK_CONDITIONS() && LoadTasks.HasItems())
|
|
||||||
{
|
|
||||||
// Find a task that can be executed (some tasks may be waiting for other tasks to finish so they are not queued yet)
|
|
||||||
int32 index = 0;
|
|
||||||
for (int32 i = 0; i < LoadTasks.Count(); i++)
|
|
||||||
{
|
|
||||||
if (LoadTasks[i]->GetContinueWithTask() == task)
|
|
||||||
{
|
|
||||||
index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ContentLoadTask* tmp = LoadTasks[index];
|
|
||||||
LoadTasks.RemoveAt(index);
|
|
||||||
|
|
||||||
PROFILE_CPU_NAMED("Inline");
|
|
||||||
ZoneColor(0xffaaaaaa);
|
|
||||||
thread->Run(tmp);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Check if task is done
|
// Check if task is done
|
||||||
if (task->IsEnded())
|
if (task->IsEnded())
|
||||||
|
|||||||
@@ -5,14 +5,14 @@
|
|||||||
#include "Engine/Threading/Task.h"
|
#include "Engine/Threading/Task.h"
|
||||||
|
|
||||||
class Asset;
|
class Asset;
|
||||||
|
class LoadingThread;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Describes content loading task object.
|
/// Describes content loading task object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class ContentLoadTask : public Task
|
class ContentLoadTask : public Task
|
||||||
{
|
{
|
||||||
friend class LoadingThread;
|
friend LoadingThread;
|
||||||
friend class ContentService;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -286,13 +286,13 @@ FlaxStorage::LockData FlaxStorage::LockSafe()
|
|||||||
|
|
||||||
uint32 FlaxStorage::GetRefCount() const
|
uint32 FlaxStorage::GetRefCount() const
|
||||||
{
|
{
|
||||||
return (uint32)Platform::AtomicRead((intptr*)&_refCount);
|
return (uint32)Platform::AtomicRead((int64*)&_refCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FlaxStorage::ShouldDispose() const
|
bool FlaxStorage::ShouldDispose() const
|
||||||
{
|
{
|
||||||
return Platform::AtomicRead((intptr*)&_refCount) == 0 &&
|
return Platform::AtomicRead((int64*)&_refCount) == 0 &&
|
||||||
Platform::AtomicRead((intptr*)&_chunksLock) == 0 &&
|
Platform::AtomicRead((int64*)&_chunksLock) == 0 &&
|
||||||
Platform::GetTimeSeconds() - _lastRefLostTime >= 0.5; // TTL in seconds
|
Platform::GetTimeSeconds() - _lastRefLostTime >= 0.5; // TTL in seconds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -87,10 +87,10 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// State
|
// State
|
||||||
intptr _refCount = 0;
|
int64 _refCount = 0;
|
||||||
intptr _chunksLock = 0;
|
int64 _chunksLock = 0;
|
||||||
intptr _files = 0;
|
int64 _files = 0;
|
||||||
intptr _isUnloadingData = 0;
|
int64 _isUnloadingData = 0;
|
||||||
double _lastRefLostTime;
|
double _lastRefLostTime;
|
||||||
CriticalSection _loadLocker;
|
CriticalSection _loadLocker;
|
||||||
|
|
||||||
|
|||||||
@@ -111,10 +111,6 @@
|
|||||||
#define _DEPRECATED(_0, _1, LASTARG, ...) LASTARG
|
#define _DEPRECATED(_0, _1, LASTARG, ...) LASTARG
|
||||||
#define DEPRECATED(...) _DEPRECATED(, ##__VA_ARGS__, _DEPRECATED_1(__VA_ARGS__), _DEPRECATED_0())
|
#define DEPRECATED(...) _DEPRECATED(, ##__VA_ARGS__, _DEPRECATED_1(__VA_ARGS__), _DEPRECATED_0())
|
||||||
|
|
||||||
#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
|
|
||||||
#define HAS_EXCEPTIONS 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// C++ 17
|
// C++ 17
|
||||||
#if __cplusplus >= 201703L
|
#if __cplusplus >= 201703L
|
||||||
#define IF_CONSTEXPR constexpr
|
#define IF_CONSTEXPR constexpr
|
||||||
|
|||||||
@@ -95,8 +95,6 @@ IMPLEMENT_ENGINE_SETTINGS_GETTER(SwitchPlatformSettings, SwitchPlatform);
|
|||||||
IMPLEMENT_ENGINE_SETTINGS_GETTER(MacPlatformSettings, MacPlatform);
|
IMPLEMENT_ENGINE_SETTINGS_GETTER(MacPlatformSettings, MacPlatform);
|
||||||
#elif PLATFORM_IOS
|
#elif PLATFORM_IOS
|
||||||
IMPLEMENT_ENGINE_SETTINGS_GETTER(iOSPlatformSettings, iOSPlatform);
|
IMPLEMENT_ENGINE_SETTINGS_GETTER(iOSPlatformSettings, iOSPlatform);
|
||||||
#elif PLATFORM_WEB
|
|
||||||
IMPLEMENT_ENGINE_SETTINGS_GETTER(WebPlatformSettings, WebPlatform);
|
|
||||||
#else
|
#else
|
||||||
#error Unknown platform
|
#error Unknown platform
|
||||||
#endif
|
#endif
|
||||||
@@ -282,7 +280,6 @@ void GameSettings::Deserialize(DeserializeStream& stream, ISerializeModifier* mo
|
|||||||
DESERIALIZE(PS5Platform);
|
DESERIALIZE(PS5Platform);
|
||||||
DESERIALIZE(MacPlatform);
|
DESERIALIZE(MacPlatform);
|
||||||
DESERIALIZE(iOSPlatform);
|
DESERIALIZE(iOSPlatform);
|
||||||
DESERIALIZE(WebPlatform);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
|
|||||||
@@ -210,14 +210,6 @@ namespace FlaxEditor.Content.Settings
|
|||||||
public JsonAsset iOSPlatform;
|
public JsonAsset iOSPlatform;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if FLAX_EDITOR || PLATFORM_WEB
|
|
||||||
/// <summary>
|
|
||||||
/// Reference to <see cref="WebPlatformSettings"/> asset. Used to apply configuration on Web platform.
|
|
||||||
/// </summary>
|
|
||||||
[EditorOrder(2110), EditorDisplay("Platform Settings", "Web"), AssetReference(typeof(WebPlatformSettings), true), Tooltip("Reference to Web Platform Settings asset")]
|
|
||||||
public JsonAsset WebPlatform;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the absolute path to the game settings asset file.
|
/// Gets the absolute path to the game settings asset file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -353,10 +345,6 @@ namespace FlaxEditor.Content.Settings
|
|||||||
if (type == typeof(iOSPlatformSettings))
|
if (type == typeof(iOSPlatformSettings))
|
||||||
return Load<iOSPlatformSettings>(gameSettings.iOSPlatform) as T;
|
return Load<iOSPlatformSettings>(gameSettings.iOSPlatform) as T;
|
||||||
#endif
|
#endif
|
||||||
#if FLAX_EDITOR || PLATFORM_WEB
|
|
||||||
if (type == typeof(WebPlatformSettings))
|
|
||||||
return Load<WebPlatformSettings>(gameSettings.WebPlatform) as T;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (gameSettings.CustomSettings != null)
|
if (gameSettings.CustomSettings != null)
|
||||||
{
|
{
|
||||||
@@ -455,10 +443,6 @@ namespace FlaxEditor.Content.Settings
|
|||||||
if (type == typeof(iOSPlatformSettings))
|
if (type == typeof(iOSPlatformSettings))
|
||||||
return gameSettings.iOSPlatform;
|
return gameSettings.iOSPlatform;
|
||||||
#endif
|
#endif
|
||||||
#if FLAX_EDITOR || PLATFORM_WEB
|
|
||||||
if (type == typeof(WebPlatformSettings))
|
|
||||||
return gameSettings.WebPlatform;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (gameSettings.CustomSettings != null)
|
if (gameSettings.CustomSettings != null)
|
||||||
{
|
{
|
||||||
@@ -573,8 +557,6 @@ namespace FlaxEditor.Content.Settings
|
|||||||
return SaveAsset(gameSettings, ref gameSettings.MacPlatform, obj);
|
return SaveAsset(gameSettings, ref gameSettings.MacPlatform, obj);
|
||||||
if (type == typeof(iOSPlatformSettings))
|
if (type == typeof(iOSPlatformSettings))
|
||||||
return SaveAsset(gameSettings, ref gameSettings.iOSPlatform, obj);
|
return SaveAsset(gameSettings, ref gameSettings.iOSPlatform, obj);
|
||||||
if (type == typeof(WebPlatformSettings))
|
|
||||||
return SaveAsset(gameSettings, ref gameSettings.WebPlatform, obj);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,6 @@ public:
|
|||||||
Guid PS5Platform;
|
Guid PS5Platform;
|
||||||
Guid MacPlatform;
|
Guid MacPlatform;
|
||||||
Guid iOSPlatform;
|
Guid iOSPlatform;
|
||||||
Guid WebPlatform;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -38,6 +38,3 @@
|
|||||||
#if PLATFORM_IOS
|
#if PLATFORM_IOS
|
||||||
#include "Engine/Platform/iOS/iOSPlatformSettings.h"
|
#include "Engine/Platform/iOS/iOSPlatformSettings.h"
|
||||||
#endif
|
#endif
|
||||||
#if PLATFORM_WEB
|
|
||||||
#include "Engine/Platform/Web/WebPlatformSettings.h"
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#define LOG_ENABLE_FILE (!PLATFORM_SWITCH && !PLATFORM_WEB)
|
#define LOG_ENABLE_FILE (!PLATFORM_SWITCH)
|
||||||
#define LOG_ENABLE_WINDOWS_SINGLE_NEW_LINE_CHAR (PLATFORM_WINDOWS && PLATFORM_DESKTOP && (USE_EDITOR || !BUILD_RELEASE))
|
#define LOG_ENABLE_WINDOWS_SINGLE_NEW_LINE_CHAR (PLATFORM_WINDOWS && PLATFORM_DESKTOP && (USE_EDITOR || !BUILD_RELEASE))
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Math.h"
|
#include "Engine/Core/Types/BaseTypes.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
namespace Math
|
namespace Math
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -153,12 +153,6 @@ public:
|
|||||||
return Math::IsOne(X) && Math::IsOne(Y) && Math::IsOne(Z) && Math::IsOne(W);
|
return Math::IsOne(X) && Math::IsOne(Y) && Math::IsOne(Z) && Math::IsOne(W);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculates the length of the vector.
|
|
||||||
T Length() const
|
|
||||||
{
|
|
||||||
return Math::Sqrt(X * X + Y * Y + Z * Z + W * W);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the average arithmetic of all the components.
|
/// Returns the average arithmetic of all the components.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public:
|
|||||||
typedef void* Tag;
|
typedef void* Tag;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class alignas(uint64) Data
|
class alignas(sizeof(void*)) Data
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
byte _data[Capacity * sizeof(T)];
|
byte _data[Capacity * sizeof(T)];
|
||||||
@@ -200,13 +200,13 @@ public:
|
|||||||
typedef void* Tag;
|
typedef void* Tag;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class alignas(sizeof(uint64)) Data
|
class alignas(sizeof(void*)) Data
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef typename FallbackAllocation::template Data<T> FallbackData;
|
typedef typename FallbackAllocation::template Data<T> FallbackData;
|
||||||
|
|
||||||
bool _useFallback = false;
|
bool _useFallback = false;
|
||||||
alignas(sizeof(uint64)) byte _data[Capacity * sizeof(T)];
|
alignas(sizeof(void*)) byte _data[Capacity * sizeof(T)];
|
||||||
FallbackData _fallback;
|
FallbackData _fallback;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
182
Source/Engine/Core/Types/CommonValue.cpp
Normal file
182
Source/Engine/Core/Types/CommonValue.cpp
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
|
#include "CommonValue.h"
|
||||||
|
#include "Engine/Scripting/ScriptingObject.h"
|
||||||
|
|
||||||
|
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||||
|
|
||||||
|
const CommonValue CommonValue::Zero(0.0f);
|
||||||
|
const CommonValue CommonValue::One(1.0f);
|
||||||
|
const CommonValue CommonValue::Null(static_cast<void*>(nullptr));
|
||||||
|
const CommonValue CommonValue::False(false);
|
||||||
|
const CommonValue CommonValue::True(true);
|
||||||
|
|
||||||
|
const Char* ToString(CommonType value)
|
||||||
|
{
|
||||||
|
const Char* result;
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case CommonType::Bool:
|
||||||
|
result = TEXT("Bool");
|
||||||
|
break;
|
||||||
|
case CommonType::Integer:
|
||||||
|
result = TEXT("Integer");
|
||||||
|
break;
|
||||||
|
case CommonType::Float:
|
||||||
|
result = TEXT("Float");
|
||||||
|
break;
|
||||||
|
case CommonType::Vector2:
|
||||||
|
result = TEXT("Vector2");
|
||||||
|
break;
|
||||||
|
case CommonType::Vector3:
|
||||||
|
result = TEXT("Vector3");
|
||||||
|
break;
|
||||||
|
case CommonType::Vector4:
|
||||||
|
result = TEXT("Vector4");
|
||||||
|
break;
|
||||||
|
case CommonType::Color:
|
||||||
|
result = TEXT("Color");
|
||||||
|
break;
|
||||||
|
case CommonType::Guid:
|
||||||
|
result = TEXT("Guid");
|
||||||
|
break;
|
||||||
|
case CommonType::String:
|
||||||
|
result = TEXT("String");
|
||||||
|
break;
|
||||||
|
case CommonType::Box:
|
||||||
|
result = TEXT("Box");
|
||||||
|
break;
|
||||||
|
case CommonType::Rotation:
|
||||||
|
result = TEXT("Rotation");
|
||||||
|
break;
|
||||||
|
case CommonType::Transform:
|
||||||
|
result = TEXT("Transform");
|
||||||
|
break;
|
||||||
|
case CommonType::Sphere:
|
||||||
|
result = TEXT("Sphere");
|
||||||
|
break;
|
||||||
|
case CommonType::Rectangle:
|
||||||
|
result = TEXT("Rectangle");
|
||||||
|
break;
|
||||||
|
case CommonType::Pointer:
|
||||||
|
result = TEXT("Pointer");
|
||||||
|
break;
|
||||||
|
case CommonType::Matrix:
|
||||||
|
result = TEXT("Matrix");
|
||||||
|
break;
|
||||||
|
case CommonType::Blob:
|
||||||
|
result = TEXT("Blob");
|
||||||
|
break;
|
||||||
|
case CommonType::Object:
|
||||||
|
result = TEXT("Object");
|
||||||
|
break;
|
||||||
|
case CommonType::Ray:
|
||||||
|
result = TEXT("Ray");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = TEXT("");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CommonValue::NearEqual(const CommonValue& a, const CommonValue& b, float epsilon)
|
||||||
|
{
|
||||||
|
ASSERT(a.Type == b.Type);
|
||||||
|
switch (a.Type)
|
||||||
|
{
|
||||||
|
case CommonType::Bool:
|
||||||
|
return a.AsBool == b.AsBool;
|
||||||
|
case CommonType::Integer:
|
||||||
|
return Math::Abs(a.AsInteger - b.AsInteger) < epsilon;
|
||||||
|
case CommonType::Float:
|
||||||
|
return Math::Abs(a.AsFloat - b.AsFloat) < epsilon;
|
||||||
|
case CommonType::Vector2:
|
||||||
|
return Float2::NearEqual(a.AsVector2, b.AsVector2, epsilon);
|
||||||
|
case CommonType::Vector3:
|
||||||
|
return Float3::NearEqual(a.AsVector3, b.AsVector3, epsilon);
|
||||||
|
case CommonType::Vector4:
|
||||||
|
return Float4::NearEqual(a.AsVector4, b.AsVector4, epsilon);
|
||||||
|
case CommonType::Color:
|
||||||
|
return Color::NearEqual(a.AsColor, b.AsColor, epsilon);
|
||||||
|
case CommonType::Guid:
|
||||||
|
return a.AsGuid == b.AsGuid;
|
||||||
|
case CommonType::String:
|
||||||
|
return StringUtils::Compare(a.AsString, b.AsString) > 0;
|
||||||
|
case CommonType::Box:
|
||||||
|
return BoundingBox::NearEqual(a.AsBox, b.AsBox, epsilon);
|
||||||
|
case CommonType::Rotation:
|
||||||
|
return Quaternion::NearEqual(a.AsRotation, b.AsRotation, epsilon);
|
||||||
|
case CommonType::Transform:
|
||||||
|
return Transform::NearEqual(a.AsTransform, b.AsTransform, epsilon);
|
||||||
|
case CommonType::Sphere:
|
||||||
|
return BoundingSphere::NearEqual(a.AsSphere, b.AsSphere, epsilon);
|
||||||
|
case CommonType::Rectangle:
|
||||||
|
return Rectangle::NearEqual(a.AsRectangle, b.AsRectangle, epsilon);
|
||||||
|
case CommonType::Ray:
|
||||||
|
return Ray::NearEqual(a.AsRay, b.AsRay, epsilon);
|
||||||
|
case CommonType::Pointer:
|
||||||
|
case CommonType::Object:
|
||||||
|
return a.AsPointer == b.AsPointer;
|
||||||
|
case CommonType::Matrix:
|
||||||
|
return a.AsMatrix == b.AsMatrix;
|
||||||
|
case CommonType::Blob:
|
||||||
|
return a.AsBlob.Length == b.AsBlob.Length;
|
||||||
|
default: CRASH;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CommonValue CommonValue::Lerp(const CommonValue& a, const CommonValue& b, float alpha)
|
||||||
|
{
|
||||||
|
ASSERT(a.Type == b.Type);
|
||||||
|
switch (a.Type)
|
||||||
|
{
|
||||||
|
case CommonType::Bool:
|
||||||
|
return alpha < 0.5f ? a : b;
|
||||||
|
case CommonType::Integer:
|
||||||
|
return Math::Lerp(a.AsInteger, b.AsInteger, alpha);
|
||||||
|
case CommonType::Float:
|
||||||
|
return Math::Lerp(a.AsFloat, b.AsFloat, alpha);
|
||||||
|
case CommonType::Vector2:
|
||||||
|
return Float2::Lerp(a.AsVector2, b.AsVector2, alpha);
|
||||||
|
case CommonType::Vector3:
|
||||||
|
return Float3::Lerp(a.AsVector3, b.AsVector3, alpha);
|
||||||
|
case CommonType::Vector4:
|
||||||
|
return Float4::Lerp(a.AsVector4, b.AsVector4, alpha);
|
||||||
|
case CommonType::Color:
|
||||||
|
return Color::Lerp(a.AsColor, b.AsColor, alpha);
|
||||||
|
case CommonType::Box:
|
||||||
|
return BoundingBox(Vector3::Lerp(a.AsBox.Minimum, b.AsBox.Minimum, alpha), Vector3::Lerp(a.AsBox.Maximum, b.AsBox.Maximum, alpha));
|
||||||
|
case CommonType::Rotation:
|
||||||
|
return Quaternion::Lerp(a.AsRotation, b.AsRotation, alpha);
|
||||||
|
case CommonType::Transform:
|
||||||
|
return Transform::Lerp(a.AsTransform, b.AsTransform, alpha);
|
||||||
|
case CommonType::Sphere:
|
||||||
|
return BoundingSphere(Vector3::Lerp(a.AsSphere.Center, b.AsSphere.Center, alpha), Math::Lerp(a.AsSphere.Radius, b.AsSphere.Radius, alpha));
|
||||||
|
case CommonType::Rectangle:
|
||||||
|
return Rectangle(Float2::Lerp(a.AsRectangle.Location, b.AsRectangle.Location, alpha), Float2::Lerp(a.AsRectangle.Size, b.AsRectangle.Size, alpha));
|
||||||
|
case CommonType::Ray:
|
||||||
|
return Ray(Vector3::Lerp(a.AsRay.Position, b.AsRay.Position, alpha), Vector3::Normalize(Vector3::Lerp(a.AsRay.Direction, b.AsRay.Direction, alpha)));
|
||||||
|
default:
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Guid CommonValue::GetObjectId() const
|
||||||
|
{
|
||||||
|
ASSERT(Type == CommonType::Object);
|
||||||
|
return AsObject ? AsObject->GetID() : Guid::Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommonValue::LinkObject()
|
||||||
|
{
|
||||||
|
AsObject->Deleted.Bind<CommonValue, &CommonValue::OnObjectDeleted>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommonValue::UnlinkObject()
|
||||||
|
{
|
||||||
|
AsObject->Deleted.Unbind<CommonValue, &CommonValue::OnObjectDeleted>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||||
1144
Source/Engine/Core/Types/CommonValue.h
Normal file
1144
Source/Engine/Core/Types/CommonValue.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
#include "Variant.h"
|
#include "Variant.h"
|
||||||
|
#include "CommonValue.h"
|
||||||
#include "Engine/Core/Collections/HashFunctions.h"
|
#include "Engine/Core/Collections/HashFunctions.h"
|
||||||
#include "Engine/Core/Collections/Dictionary.h"
|
#include "Engine/Core/Collections/Dictionary.h"
|
||||||
#include "Engine/Content/Asset.h"
|
#include "Engine/Content/Asset.h"
|
||||||
@@ -963,6 +964,78 @@ Variant::Variant(const Span<byte>& v)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||||
|
#include "Engine/Content/Deprecated.h"
|
||||||
|
Variant::Variant(const CommonValue& value)
|
||||||
|
: Variant()
|
||||||
|
{
|
||||||
|
// [Deprecated on 31.07.2020, expires on 31.07.2022]
|
||||||
|
MARK_CONTENT_DEPRECATED();
|
||||||
|
switch (value.Type)
|
||||||
|
{
|
||||||
|
case CommonType::Bool:
|
||||||
|
*this = value.AsBool;
|
||||||
|
break;
|
||||||
|
case CommonType::Integer:
|
||||||
|
*this = value.AsInteger;
|
||||||
|
break;
|
||||||
|
case CommonType::Float:
|
||||||
|
*this = value.AsFloat;
|
||||||
|
break;
|
||||||
|
case CommonType::Vector2:
|
||||||
|
*this = value.AsVector2;
|
||||||
|
break;
|
||||||
|
case CommonType::Vector3:
|
||||||
|
*this = value.AsVector3;
|
||||||
|
break;
|
||||||
|
case CommonType::Vector4:
|
||||||
|
*this = value.AsVector4;
|
||||||
|
break;
|
||||||
|
case CommonType::Color:
|
||||||
|
*this = value.AsColor;
|
||||||
|
break;
|
||||||
|
case CommonType::Guid:
|
||||||
|
*this = value.AsGuid;
|
||||||
|
break;
|
||||||
|
case CommonType::String:
|
||||||
|
SetString(StringView(value.AsString));
|
||||||
|
break;
|
||||||
|
case CommonType::Box:
|
||||||
|
*this = Variant(value.AsBox);
|
||||||
|
break;
|
||||||
|
case CommonType::Rotation:
|
||||||
|
*this = value.AsRotation;
|
||||||
|
break;
|
||||||
|
case CommonType::Transform:
|
||||||
|
*this = Variant(value.AsTransform);
|
||||||
|
break;
|
||||||
|
case CommonType::Sphere:
|
||||||
|
*this = value.AsSphere;
|
||||||
|
break;
|
||||||
|
case CommonType::Rectangle:
|
||||||
|
*this = value.AsRectangle;
|
||||||
|
break;
|
||||||
|
case CommonType::Pointer:
|
||||||
|
*this = value.AsPointer;
|
||||||
|
break;
|
||||||
|
case CommonType::Matrix:
|
||||||
|
*this = Variant(value.AsMatrix);
|
||||||
|
break;
|
||||||
|
case CommonType::Blob:
|
||||||
|
SetBlob(value.AsBlob.Data, value.AsBlob.Length);
|
||||||
|
break;
|
||||||
|
case CommonType::Object:
|
||||||
|
SetObject(value.AsObject);
|
||||||
|
break;
|
||||||
|
case CommonType::Ray:
|
||||||
|
*this = Variant(value.AsRay);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CRASH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||||
|
|
||||||
Variant::~Variant()
|
Variant::~Variant()
|
||||||
{
|
{
|
||||||
switch (Type.Type)
|
switch (Type.Type)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
class Asset;
|
class Asset;
|
||||||
struct Transform;
|
struct Transform;
|
||||||
|
struct CommonValue;
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class AssetReference;
|
class AssetReference;
|
||||||
struct ScriptingTypeHandle;
|
struct ScriptingTypeHandle;
|
||||||
@@ -263,6 +264,7 @@ public:
|
|||||||
explicit Variant(Dictionary<Variant, Variant, HeapAllocation>&& v);
|
explicit Variant(Dictionary<Variant, Variant, HeapAllocation>&& v);
|
||||||
explicit Variant(const Dictionary<Variant, Variant, HeapAllocation>& v);
|
explicit Variant(const Dictionary<Variant, Variant, HeapAllocation>& v);
|
||||||
explicit Variant(const Span<byte>& v);
|
explicit Variant(const Span<byte>& v);
|
||||||
|
explicit Variant(const CommonValue& v);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Variant(const class AssetReference<T>& v)
|
Variant(const class AssetReference<T>& v)
|
||||||
|
|||||||
@@ -26,8 +26,6 @@
|
|||||||
#include "Mac/MacGame.h"
|
#include "Mac/MacGame.h"
|
||||||
#elif PLATFORM_IOS
|
#elif PLATFORM_IOS
|
||||||
#include "iOS/iOSGame.h"
|
#include "iOS/iOSGame.h"
|
||||||
#elif PLATFORM_WEB
|
|
||||||
#include "Web/WebGame.h"
|
|
||||||
#else
|
#else
|
||||||
#error Missing Game implementation!
|
#error Missing Game implementation!
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2,12 +2,60 @@
|
|||||||
|
|
||||||
#include "GameplayGlobals.h"
|
#include "GameplayGlobals.h"
|
||||||
#include "Engine/Core/Log.h"
|
#include "Engine/Core/Log.h"
|
||||||
|
#include "Engine/Core/Types/CommonValue.h"
|
||||||
#include "Engine/Serialization/MemoryReadStream.h"
|
#include "Engine/Serialization/MemoryReadStream.h"
|
||||||
#include "Engine/Serialization/MemoryWriteStream.h"
|
#include "Engine/Serialization/MemoryWriteStream.h"
|
||||||
#include "Engine/Content/Factories/BinaryAssetFactory.h"
|
#include "Engine/Content/Factories/BinaryAssetFactory.h"
|
||||||
|
#include "Engine/Content/Upgraders/BinaryAssetUpgrader.h"
|
||||||
#include "Engine/Threading/Threading.h"
|
#include "Engine/Threading/Threading.h"
|
||||||
|
|
||||||
REGISTER_BINARY_ASSET(GameplayGlobals, "FlaxEngine.GameplayGlobals", true);
|
#if USE_EDITOR
|
||||||
|
|
||||||
|
class GameplayGlobalsUpgrader : public BinaryAssetUpgrader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GameplayGlobalsUpgrader()
|
||||||
|
{
|
||||||
|
const Upgrader upgraders[] =
|
||||||
|
{
|
||||||
|
{ 1, 2, &Upgrade_1_To_2 }, // [Deprecated on 31.07.2020, expires on 31.07.2022]
|
||||||
|
};
|
||||||
|
setup(upgraders, ARRAY_COUNT(upgraders));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool Upgrade_1_To_2(AssetMigrationContext& context)
|
||||||
|
{
|
||||||
|
// [Deprecated on 31.07.2020, expires on 31.07.2022]
|
||||||
|
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||||
|
ASSERT(context.Input.SerializedVersion == 1 && context.Output.SerializedVersion == 2);
|
||||||
|
if (context.AllocateChunk(0))
|
||||||
|
return true;
|
||||||
|
auto& data = context.Input.Header.Chunks[0]->Data;
|
||||||
|
MemoryReadStream stream(data.Get(), data.Length());
|
||||||
|
MemoryWriteStream output;
|
||||||
|
int32 count;
|
||||||
|
stream.ReadInt32(&count);
|
||||||
|
output.WriteInt32(count);
|
||||||
|
String name;
|
||||||
|
for (int32 i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
stream.Read(name, 71);
|
||||||
|
CommonValue commonValue;
|
||||||
|
stream.ReadCommonValue(&commonValue);
|
||||||
|
Variant variant(commonValue);
|
||||||
|
output.WriteVariant(variant);
|
||||||
|
}
|
||||||
|
context.Output.Header.Chunks[0]->Data.Copy(output.GetHandle(), output.GetPosition());
|
||||||
|
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
REGISTER_BINARY_ASSET_WITH_UPGRADER(GameplayGlobals, "FlaxEngine.GameplayGlobals", GameplayGlobalsUpgrader, true);
|
||||||
|
|
||||||
GameplayGlobals::GameplayGlobals(const SpawnParams& params, const AssetInfo* info)
|
GameplayGlobals::GameplayGlobals(const SpawnParams& params, const AssetInfo* info)
|
||||||
: BinaryAsset(params, info)
|
: BinaryAsset(params, info)
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if PLATFORM_WEB
|
|
||||||
|
|
||||||
#include "../Base/GameBase.h"
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The game class implementation for Web platform.
|
|
||||||
/// </summary>
|
|
||||||
/// <seealso cref="Game" />
|
|
||||||
class WebGame : public GameBase
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef WebGame Game;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -45,9 +45,7 @@
|
|||||||
#define GPU_USE_WINDOW_SRV 1
|
#define GPU_USE_WINDOW_SRV 1
|
||||||
|
|
||||||
// True if allow graphics profile events and markers
|
// True if allow graphics profile events and markers
|
||||||
#ifndef GPU_ALLOW_PROFILE_EVENTS
|
|
||||||
#define GPU_ALLOW_PROFILE_EVENTS (!BUILD_RELEASE)
|
#define GPU_ALLOW_PROFILE_EVENTS (!BUILD_RELEASE)
|
||||||
#endif
|
|
||||||
|
|
||||||
// True if allow hardware tessellation shaders (Hull and Domain shaders)
|
// True if allow hardware tessellation shaders (Hull and Domain shaders)
|
||||||
#ifndef GPU_ALLOW_TESSELLATION_SHADERS
|
#ifndef GPU_ALLOW_TESSELLATION_SHADERS
|
||||||
@@ -60,9 +58,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Enable/disable creating GPU resources on separate threads (otherwise only the main thread can be used)
|
// Enable/disable creating GPU resources on separate threads (otherwise only the main thread can be used)
|
||||||
#ifndef GPU_ENABLE_ASYNC_RESOURCES_CREATION
|
|
||||||
#define GPU_ENABLE_ASYNC_RESOURCES_CREATION 1
|
#define GPU_ENABLE_ASYNC_RESOURCES_CREATION 1
|
||||||
#endif
|
|
||||||
|
|
||||||
// Enable/disable force shaders recompilation
|
// Enable/disable force shaders recompilation
|
||||||
#define GPU_FORCE_RECOMPILE_SHADERS 0
|
#define GPU_FORCE_RECOMPILE_SHADERS 0
|
||||||
|
|||||||
@@ -96,10 +96,6 @@ public class Graphics : EngineModule
|
|||||||
else
|
else
|
||||||
Log.WarningOnce(string.Format("Building for {0} without Vulkan rendering backend (Vulkan SDK is missing)", options.Platform.Target), ref _logMissingVulkanSDK);
|
Log.WarningOnce(string.Format("Building for {0} without Vulkan rendering backend (Vulkan SDK is missing)", options.Platform.Target), ref _logMissingVulkanSDK);
|
||||||
break;
|
break;
|
||||||
case TargetPlatform.Web:
|
|
||||||
options.PrivateDependencies.Add("GraphicsDeviceNull");
|
|
||||||
// TODO: add WebGPU
|
|
||||||
break;
|
|
||||||
default: throw new InvalidPlatformException(options.Platform.Target);
|
default: throw new InvalidPlatformException(options.Platform.Target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ struct TIsPODType<SkeletonBone>
|
|||||||
class FLAXENGINE_API SkeletonData
|
class FLAXENGINE_API SkeletonData
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
mutable volatile intptr _dirty = 1;
|
mutable volatile int64 _dirty = 1;
|
||||||
mutable Array<Matrix> _cachedPose;
|
mutable Array<Matrix> _cachedPose;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ GPUTexture* RenderBuffers::RequestHiZ(GPUContext* context, bool fullRes, int32 m
|
|||||||
|
|
||||||
// Allocate or resize buffer (with full mip-chain)
|
// Allocate or resize buffer (with full mip-chain)
|
||||||
// TODO: migrate to inverse depth and try using r16 again as default (should have no artifacts anymore)
|
// TODO: migrate to inverse depth and try using r16 again as default (should have no artifacts anymore)
|
||||||
auto format = PLATFORM_WEB || PLATFORM_ANDROID || PLATFORM_IOS || PLATFORM_SWITCH ? PixelFormat::R16_UInt : PixelFormat::R32_Float;
|
auto format = PLATFORM_ANDROID || PLATFORM_IOS || PLATFORM_SWITCH ? PixelFormat::R16_UInt : PixelFormat::R32_Float;
|
||||||
auto width = fullRes ? _width : Math::Max(_width >> 1, 1);
|
auto width = fullRes ? _width : Math::Max(_width >> 1, 1);
|
||||||
auto height = fullRes ? _height : Math::Max(_height >> 1, 1);
|
auto height = fullRes ? _height : Math::Max(_height >> 1, 1);
|
||||||
auto desc = GPUTextureDescription::New2D(width, height, mipLevels, format, GPUTextureFlags::ShaderResource);
|
auto desc = GPUTextureDescription::New2D(width, height, mipLevels, format, GPUTextureFlags::ShaderResource);
|
||||||
|
|||||||
@@ -428,9 +428,7 @@ void LevelService::LateFixedUpdate()
|
|||||||
|
|
||||||
void LevelService::Dispose()
|
void LevelService::Dispose()
|
||||||
{
|
{
|
||||||
// End scene actions
|
|
||||||
ScopeLock lock(_sceneActionsLocker);
|
ScopeLock lock(_sceneActionsLocker);
|
||||||
_sceneActions.ClearDelete();
|
|
||||||
|
|
||||||
// Unload scenes
|
// Unload scenes
|
||||||
unloadScenes();
|
unloadScenes();
|
||||||
|
|||||||
@@ -88,7 +88,6 @@ void SceneRendering::Draw(RenderContextBatch& renderContextBatch, DrawCategory c
|
|||||||
|
|
||||||
// Draw all visual components
|
// Draw all visual components
|
||||||
_drawListIndex = -1;
|
_drawListIndex = -1;
|
||||||
#if PLATFORM_THREADS_LIMIT > 1
|
|
||||||
if (_drawListSize >= 64 && category == SceneDrawAsync && renderContextBatch.EnableAsync)
|
if (_drawListSize >= 64 && category == SceneDrawAsync && renderContextBatch.EnableAsync)
|
||||||
{
|
{
|
||||||
// Run in async via Job System
|
// Run in async via Job System
|
||||||
@@ -98,7 +97,6 @@ void SceneRendering::Draw(RenderContextBatch& renderContextBatch, DrawCategory c
|
|||||||
renderContextBatch.WaitLabels.Add(waitLabel);
|
renderContextBatch.WaitLabels.Add(waitLabel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
// Scene is small so draw on a main-thread
|
// Scene is small so draw on a main-thread
|
||||||
DrawActorsJob(0);
|
DrawActorsJob(0);
|
||||||
|
|||||||
@@ -262,7 +262,6 @@ void LocalizationService::OnLocalizationChanged()
|
|||||||
localeName[currentCulture.Length() + 5] = '8';
|
localeName[currentCulture.Length() + 5] = '8';
|
||||||
localeName[currentCulture.Length() + 6] = 0;
|
localeName[currentCulture.Length() + 6] = 0;
|
||||||
}
|
}
|
||||||
#if HAS_EXCEPTIONS
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::locale::global(std::locale(localeName));
|
std::locale::global(std::locale(localeName));
|
||||||
@@ -273,9 +272,6 @@ void LocalizationService::OnLocalizationChanged()
|
|||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
std::locale::global(std::locale(localeName));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -74,9 +74,6 @@ public class Main : EngineModule
|
|||||||
case TargetPlatform.iOS:
|
case TargetPlatform.iOS:
|
||||||
options.SourcePaths.Add(Path.Combine(FolderPath, "Default"));
|
options.SourcePaths.Add(Path.Combine(FolderPath, "Default"));
|
||||||
break;
|
break;
|
||||||
case TargetPlatform.Web:
|
|
||||||
options.SourcePaths.Add(Path.Combine(FolderPath, "Web"));
|
|
||||||
break;
|
|
||||||
default: throw new InvalidPlatformException(options.Platform.Target);
|
default: throw new InvalidPlatformException(options.Platform.Target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
||||||
|
|
||||||
#if PLATFORM_WEB
|
|
||||||
|
|
||||||
#include "Engine/Engine/Engine.h"
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
return Engine::Main(TEXT(""));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -6,6 +6,23 @@
|
|||||||
|
|
||||||
class ScriptingObject;
|
class ScriptingObject;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Network driver implementations enum.
|
||||||
|
/// [Deprecated in v1.3]
|
||||||
|
/// </summary>
|
||||||
|
API_ENUM(Namespace="FlaxEngine.Networking") enum class DEPRECATED() NetworkDriverType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Invalid network driver implementation.
|
||||||
|
/// </summary>
|
||||||
|
Undefined = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ENet library based network driver implementation.
|
||||||
|
/// </summary>
|
||||||
|
ENet
|
||||||
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Low-level network configuration structure. Provides settings for the network driver and all internal components.
|
/// Low-level network configuration structure. Provides settings for the network driver and all internal components.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -13,6 +30,14 @@ API_STRUCT(Namespace="FlaxEngine.Networking") struct FLAXENGINE_API NetworkConfi
|
|||||||
{
|
{
|
||||||
DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkConfig);
|
DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkConfig);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The network driver that will be used to create the peer.
|
||||||
|
/// To allow two peers to connect, they must use the same host.
|
||||||
|
/// [Deprecated in v1.3]
|
||||||
|
/// </summary>
|
||||||
|
API_FIELD()
|
||||||
|
DEPRECATED("Use NetworkDriver field instead") NetworkDriverType NetworkDriverType;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The network driver instance (implements INetworkDriver) that will be used to create and manage the peer, send and receive messages.
|
/// The network driver instance (implements INetworkDriver) that will be used to create and manage the peer, send and receive messages.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -56,4 +81,15 @@ API_STRUCT(Namespace="FlaxEngine.Networking") struct FLAXENGINE_API NetworkConfi
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
API_FIELD()
|
API_FIELD()
|
||||||
uint16 MessagePoolSize = 2048;
|
uint16 MessagePoolSize = 2048;
|
||||||
|
|
||||||
|
// Ignore deprecation warnings in defaults
|
||||||
|
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||||
|
NetworkConfig()
|
||||||
|
{
|
||||||
|
NetworkDriverType = NetworkDriverType::ENet;
|
||||||
|
}
|
||||||
|
NetworkConfig(const NetworkConfig& other) = default;
|
||||||
|
NetworkConfig(NetworkConfig&& other) = default;
|
||||||
|
NetworkConfig& operator=(const NetworkConfig& other) = default;
|
||||||
|
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,6 +22,10 @@ bool NetworkPeer::Initialize(const NetworkConfig& config)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
Config = config;
|
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)
|
if (Config.NetworkDriver == nullptr)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
#if COMPILE_WITH_PARTICLE_GPU_GRAPH
|
#if COMPILE_WITH_PARTICLE_GPU_GRAPH
|
||||||
|
|
||||||
#include "ParticleEmitterGraph.GPU.h"
|
#include "ParticleEmitterGraph.GPU.h"
|
||||||
#include "Engine/Core/Math/Matrix.h"
|
|
||||||
#include "Engine/Serialization/FileReadStream.h"
|
#include "Engine/Serialization/FileReadStream.h"
|
||||||
#include "Engine/Visject/ShaderGraphUtilities.h"
|
#include "Engine/Visject/ShaderGraphUtilities.h"
|
||||||
#include "Engine/Engine/Globals.h"
|
#include "Engine/Engine/Globals.h"
|
||||||
|
#include "Engine/Core/Types/CommonValue.h"
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// GPU particles shader source code template has special marks for generated code.
|
/// GPU particles shader source code template has special marks for generated code.
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "ParticleEffect.h"
|
#include "ParticleEffect.h"
|
||||||
#include "Particles.h"
|
#include "Particles.h"
|
||||||
|
#include "Engine/Core/Types/CommonValue.h"
|
||||||
#include "Engine/Content/Deprecated.h"
|
#include "Engine/Content/Deprecated.h"
|
||||||
#include "Engine/Serialization/JsonTools.h"
|
#include "Engine/Serialization/JsonTools.h"
|
||||||
#include "Engine/Serialization/Serialization.h"
|
#include "Engine/Serialization/Serialization.h"
|
||||||
@@ -727,39 +728,86 @@ void ParticleEffect::Deserialize(DeserializeStream& stream, ISerializeModifier*
|
|||||||
const auto overridesMember = stream.FindMember("Overrides");
|
const auto overridesMember = stream.FindMember("Overrides");
|
||||||
if (overridesMember != stream.MemberEnd())
|
if (overridesMember != stream.MemberEnd())
|
||||||
{
|
{
|
||||||
const auto& overrides = overridesMember->value;
|
// [Deprecated on 25.11.2018, expires on 25.11.2022]
|
||||||
CHECK(overrides.IsArray());
|
if (modifier->EngineBuild < 6197)
|
||||||
_parametersOverrides.EnsureCapacity(_parametersOverrides.Count() + overrides.Size());
|
|
||||||
for (rapidjson::SizeType i = 0; i < overrides.Size(); i++)
|
|
||||||
{
|
{
|
||||||
auto& o = (DeserializeStream&)overrides[i];
|
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||||
const String trackName = JsonTools::GetString(o, "Track");
|
MARK_CONTENT_DEPRECATED();
|
||||||
const Guid id = JsonTools::GetGuid(o, "Id");
|
const auto& overrides = overridesMember->value;
|
||||||
ParameterOverride* e = nullptr;
|
ASSERT(overrides.IsArray());
|
||||||
for (auto& q : _parametersOverrides)
|
_parametersOverrides.EnsureCapacity(_parametersOverrides.Count() + overrides.Size());
|
||||||
|
for (rapidjson::SizeType i = 0; i < overrides.Size(); i++)
|
||||||
{
|
{
|
||||||
if (q.Id == id && q.Track == trackName)
|
const auto& o = (DeserializeStream&)overrides[i];
|
||||||
|
const String trackName = JsonTools::GetString(o, "Track");
|
||||||
|
const Guid id = JsonTools::GetGuid(o, "Id");
|
||||||
|
ParameterOverride* e = nullptr;
|
||||||
|
for (auto& q : _parametersOverrides)
|
||||||
{
|
{
|
||||||
e = &q;
|
if (q.Id == id && q.Track == trackName)
|
||||||
break;
|
{
|
||||||
|
e = &q;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (e)
|
||||||
|
{
|
||||||
|
// Update overriden parameter value
|
||||||
|
CommonValue value;
|
||||||
|
auto mValue = SERIALIZE_FIND_MEMBER(o, "Value");
|
||||||
|
if (mValue != o.MemberEnd())
|
||||||
|
e->Value = Variant(JsonTools::GetCommonValue(mValue->value));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Add parameter override
|
||||||
|
auto& p = _parametersOverrides.AddOne();
|
||||||
|
p.Track = trackName;
|
||||||
|
p.Id = id;
|
||||||
|
CommonValue value;
|
||||||
|
auto mValue = SERIALIZE_FIND_MEMBER(o, "Value");
|
||||||
|
if (mValue != o.MemberEnd())
|
||||||
|
p.Value = Variant(JsonTools::GetCommonValue(mValue->value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (e)
|
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto& overrides = overridesMember->value;
|
||||||
|
ASSERT(overrides.IsArray());
|
||||||
|
_parametersOverrides.EnsureCapacity(_parametersOverrides.Count() + overrides.Size());
|
||||||
|
for (rapidjson::SizeType i = 0; i < overrides.Size(); i++)
|
||||||
{
|
{
|
||||||
// Update overriden parameter value
|
auto& o = (DeserializeStream&)overrides[i];
|
||||||
const auto mValue = SERIALIZE_FIND_MEMBER(o, "Value");
|
const String trackName = JsonTools::GetString(o, "Track");
|
||||||
if (mValue != stream.MemberEnd())
|
const Guid id = JsonTools::GetGuid(o, "Id");
|
||||||
Serialization::Deserialize(mValue->value, e->Value, modifier);
|
ParameterOverride* e = nullptr;
|
||||||
}
|
for (auto& q : _parametersOverrides)
|
||||||
else
|
{
|
||||||
{
|
if (q.Id == id && q.Track == trackName)
|
||||||
// Add parameter override
|
{
|
||||||
auto& p = _parametersOverrides.AddOne();
|
e = &q;
|
||||||
p.Track = trackName;
|
break;
|
||||||
p.Id = id;
|
}
|
||||||
const auto mValue = SERIALIZE_FIND_MEMBER(o, "Value");
|
}
|
||||||
if (mValue != stream.MemberEnd())
|
if (e)
|
||||||
Serialization::Deserialize(mValue->value, p.Value, modifier);
|
{
|
||||||
|
// Update overriden parameter value
|
||||||
|
const auto mValue = SERIALIZE_FIND_MEMBER(o, "Value");
|
||||||
|
if (mValue != stream.MemberEnd())
|
||||||
|
Serialization::Deserialize(mValue->value, e->Value, modifier);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Add parameter override
|
||||||
|
auto& p = _parametersOverrides.AddOne();
|
||||||
|
p.Track = trackName;
|
||||||
|
p.Id = id;
|
||||||
|
const auto mValue = SERIALIZE_FIND_MEMBER(o, "Value");
|
||||||
|
if (mValue != stream.MemberEnd())
|
||||||
|
Serialization::Deserialize(mValue->value, p.Value, modifier);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include "ParticleSystem.h"
|
#include "ParticleSystem.h"
|
||||||
#include "ParticleEffect.h"
|
#include "ParticleEffect.h"
|
||||||
#include "Particles.h"
|
#include "Particles.h"
|
||||||
#include "Engine/Content/Deprecated.h"
|
|
||||||
#include "Engine/Content/Factories/BinaryAssetFactory.h"
|
#include "Engine/Content/Factories/BinaryAssetFactory.h"
|
||||||
#include "Engine/Content/Upgraders/ShaderAssetUpgrader.h"
|
#include "Engine/Content/Upgraders/ShaderAssetUpgrader.h"
|
||||||
#include "Engine/Core/Log.h"
|
#include "Engine/Core/Log.h"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "ParticleSystem.h"
|
#include "ParticleSystem.h"
|
||||||
#include "ParticleEffect.h"
|
#include "ParticleEffect.h"
|
||||||
|
#include "Engine/Core/Types/CommonValue.h"
|
||||||
#include "Engine/Level/Level.h"
|
#include "Engine/Level/Level.h"
|
||||||
#include "Engine/Content/Deprecated.h"
|
#include "Engine/Content/Deprecated.h"
|
||||||
#include "Engine/Content/Factories/BinaryAssetFactory.h"
|
#include "Engine/Content/Factories/BinaryAssetFactory.h"
|
||||||
@@ -224,6 +225,158 @@ Asset::LoadResult ParticleSystem::load()
|
|||||||
#endif
|
#endif
|
||||||
switch (version)
|
switch (version)
|
||||||
{
|
{
|
||||||
|
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
// [Deprecated on 23.07.2019, expires on 27.04.2021]
|
||||||
|
MARK_CONTENT_DEPRECATED();
|
||||||
|
|
||||||
|
// Load properties
|
||||||
|
stream.ReadFloat(&FramesPerSecond);
|
||||||
|
stream.ReadInt32(&DurationFrames);
|
||||||
|
|
||||||
|
// Load emitters
|
||||||
|
int32 emittersCount;
|
||||||
|
stream.ReadInt32(&emittersCount);
|
||||||
|
Emitters.Resize(emittersCount, false);
|
||||||
|
|
||||||
|
// Load tracks
|
||||||
|
Guid id;
|
||||||
|
int32 tracksCount;
|
||||||
|
stream.ReadInt32(&tracksCount);
|
||||||
|
Tracks.Resize(tracksCount, false);
|
||||||
|
for (int32 i = 0; i < tracksCount; i++)
|
||||||
|
{
|
||||||
|
auto& track = Tracks[i];
|
||||||
|
|
||||||
|
track.Type = (Track::Types)stream.ReadByte();
|
||||||
|
track.Flag = (Track::Flags)stream.ReadByte();
|
||||||
|
stream.ReadInt32(&track.ParentIndex);
|
||||||
|
stream.ReadInt32(&track.ChildrenCount);
|
||||||
|
stream.ReadString(&track.Name, -13);
|
||||||
|
track.Disabled = (int32)track.Flag & (int32)Track::Flags::Mute || (track.ParentIndex != -1 && Tracks[track.ParentIndex].Disabled);
|
||||||
|
|
||||||
|
switch (track.Type)
|
||||||
|
{
|
||||||
|
case Track::Types::Emitter:
|
||||||
|
stream.Read(id);
|
||||||
|
stream.ReadInt32(&track.AsEmitter.Index);
|
||||||
|
stream.ReadInt32(&track.AsEmitter.StartFrame);
|
||||||
|
stream.ReadInt32(&track.AsEmitter.DurationFrames);
|
||||||
|
Emitters[track.AsEmitter.Index] = id;
|
||||||
|
break;
|
||||||
|
case Track::Types::Folder:
|
||||||
|
stream.Read(track.Color);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return LoadResult::InvalidData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for all tracks to be loaded - particle system cannot be used if any of the emitters is not loaded yet
|
||||||
|
// Note: this loop might trigger loading referenced assets on this thread
|
||||||
|
for (int32 i = 0; i < Emitters.Count(); i++)
|
||||||
|
{
|
||||||
|
if (Emitters[i])
|
||||||
|
Emitters[i]->WaitForLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load parameters overrides
|
||||||
|
int32 overridesCount = 0;
|
||||||
|
if (stream.CanRead())
|
||||||
|
stream.ReadInt32(&overridesCount);
|
||||||
|
if (overridesCount != 0)
|
||||||
|
{
|
||||||
|
EmitterParameterOverrideKey key;
|
||||||
|
CommonValue value;
|
||||||
|
for (int32 i = 0; i < overridesCount; i++)
|
||||||
|
{
|
||||||
|
stream.ReadInt32(&key.First);
|
||||||
|
stream.Read(key.Second);
|
||||||
|
stream.ReadCommonValue(&value);
|
||||||
|
SKIP_UNUSED_PARAM_OVERRIDE();
|
||||||
|
EmittersParametersOverrides.Add(key, Variant(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
// [Deprecated on 31.07.2020, expires on 31.07.2022]
|
||||||
|
MARK_CONTENT_DEPRECATED();
|
||||||
|
|
||||||
|
// Load properties
|
||||||
|
stream.ReadFloat(&FramesPerSecond);
|
||||||
|
stream.ReadInt32(&DurationFrames);
|
||||||
|
|
||||||
|
// Load emitters
|
||||||
|
int32 emittersCount;
|
||||||
|
stream.ReadInt32(&emittersCount);
|
||||||
|
Emitters.Resize(emittersCount, false);
|
||||||
|
|
||||||
|
// Load tracks
|
||||||
|
Guid id;
|
||||||
|
int32 tracksCount;
|
||||||
|
stream.ReadInt32(&tracksCount);
|
||||||
|
Tracks.Resize(tracksCount, false);
|
||||||
|
for (int32 i = 0; i < tracksCount; i++)
|
||||||
|
{
|
||||||
|
auto& track = Tracks[i];
|
||||||
|
|
||||||
|
track.Type = (Track::Types)stream.ReadByte();
|
||||||
|
track.Flag = (Track::Flags)stream.ReadByte();
|
||||||
|
stream.ReadInt32(&track.ParentIndex);
|
||||||
|
stream.ReadInt32(&track.ChildrenCount);
|
||||||
|
stream.ReadString(&track.Name, -13);
|
||||||
|
track.Disabled = (int32)track.Flag & (int32)Track::Flags::Mute || (track.ParentIndex != -1 && Tracks[track.ParentIndex].Disabled);
|
||||||
|
stream.Read(track.Color);
|
||||||
|
|
||||||
|
switch (track.Type)
|
||||||
|
{
|
||||||
|
case Track::Types::Emitter:
|
||||||
|
stream.Read(id);
|
||||||
|
stream.ReadInt32(&track.AsEmitter.Index);
|
||||||
|
stream.ReadInt32(&track.AsEmitter.StartFrame);
|
||||||
|
stream.ReadInt32(&track.AsEmitter.DurationFrames);
|
||||||
|
Emitters[track.AsEmitter.Index] = id;
|
||||||
|
break;
|
||||||
|
case Track::Types::Folder:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return LoadResult::InvalidData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for all tracks to be loaded - particle system cannot be used if any of the emitters is not loaded yet
|
||||||
|
// Note: this loop might trigger loading referenced assets on this thread
|
||||||
|
for (int32 i = 0; i < Emitters.Count(); i++)
|
||||||
|
{
|
||||||
|
if (Emitters[i])
|
||||||
|
Emitters[i]->WaitForLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load parameters overrides
|
||||||
|
int32 overridesCount = 0;
|
||||||
|
if (stream.CanRead())
|
||||||
|
stream.ReadInt32(&overridesCount);
|
||||||
|
if (overridesCount != 0)
|
||||||
|
{
|
||||||
|
EmitterParameterOverrideKey key;
|
||||||
|
CommonValue value;
|
||||||
|
for (int32 i = 0; i < overridesCount; i++)
|
||||||
|
{
|
||||||
|
stream.ReadInt32(&key.First);
|
||||||
|
stream.Read(key.Second);
|
||||||
|
stream.ReadCommonValue(&value);
|
||||||
|
SKIP_UNUSED_PARAM_OVERRIDE();
|
||||||
|
EmittersParametersOverrides[key] = Variant(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||||
case 3: // [Deprecated on 03.09.2021 expires on 03.09.2023]
|
case 3: // [Deprecated on 03.09.2021 expires on 03.09.2023]
|
||||||
MARK_CONTENT_DEPRECATED();
|
MARK_CONTENT_DEPRECATED();
|
||||||
case 4:
|
case 4:
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ PACK_STRUCT(struct SpriteParticleVertex
|
|||||||
class SpriteParticleRenderer
|
class SpriteParticleRenderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
volatile intptr Ready = 0;
|
volatile int64 Ready = 0;
|
||||||
GPUBuffer* VB = nullptr;
|
GPUBuffer* VB = nullptr;
|
||||||
GPUBuffer* IB = nullptr;
|
GPUBuffer* IB = nullptr;
|
||||||
const static int32 VertexCount = 4;
|
const static int32 VertexCount = 4;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "Particles.h"
|
#include "Particles.h"
|
||||||
#include "Engine/Graphics/GPUBuffer.h"
|
#include "Engine/Graphics/GPUBuffer.h"
|
||||||
#include "Engine/Graphics/GPUDevice.h"
|
#include "Engine/Graphics/GPUDevice.h"
|
||||||
|
#include "Engine/Core/Types/CommonValue.h"
|
||||||
|
|
||||||
ParticleEmitterInstance::ParticleEmitterInstance()
|
ParticleEmitterInstance::ParticleEmitterInstance()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -539,35 +539,11 @@ protected:
|
|||||||
hitInfo = hit.shape ? static_cast<PhysicsColliderActor*>(hit.shape->userData) : nullptr; \
|
hitInfo = hit.shape ? static_cast<PhysicsColliderActor*>(hit.shape->userData) : nullptr; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PLATFORM_THREADS_LIMIT <= 1
|
|
||||||
|
|
||||||
class DummyCpuDispatcher : public PxCpuDispatcher
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void submitTask(PxBaseTask& task) override
|
|
||||||
{
|
|
||||||
// Run directly
|
|
||||||
PROFILE_CPU_NAMED("Physics");
|
|
||||||
task.run();
|
|
||||||
task.release();
|
|
||||||
}
|
|
||||||
uint32_t getWorkerCount() const override
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
PxFoundation* Foundation = nullptr;
|
PxFoundation* Foundation = nullptr;
|
||||||
PxPhysics* PhysX = nullptr;
|
PxPhysics* PhysX = nullptr;
|
||||||
#if PLATFORM_THREADS_LIMIT > 1
|
|
||||||
PxDefaultCpuDispatcher* CpuDispatcher = nullptr;
|
PxDefaultCpuDispatcher* CpuDispatcher = nullptr;
|
||||||
#else
|
|
||||||
DummyCpuDispatcher* CpuDispatcher = nullptr;
|
|
||||||
#endif
|
|
||||||
#if WITH_PVD
|
#if WITH_PVD
|
||||||
PxPvd* PVD = nullptr;
|
PxPvd* PVD = nullptr;
|
||||||
#endif
|
#endif
|
||||||
@@ -1760,11 +1736,7 @@ void PhysicsBackend::Shutdown()
|
|||||||
#if WITH_PVD
|
#if WITH_PVD
|
||||||
RELEASE_PHYSX(PVD);
|
RELEASE_PHYSX(PVD);
|
||||||
#endif
|
#endif
|
||||||
#if PLATFORM_THREADS_LIMIT > 1
|
|
||||||
RELEASE_PHYSX(CpuDispatcher);
|
RELEASE_PHYSX(CpuDispatcher);
|
||||||
#else
|
|
||||||
SAFE_DELETE(CpuDispatcher);
|
|
||||||
#endif
|
|
||||||
RELEASE_PHYSX(Foundation);
|
RELEASE_PHYSX(Foundation);
|
||||||
SceneOrigins.Clear();
|
SceneOrigins.Clear();
|
||||||
}
|
}
|
||||||
@@ -1824,14 +1796,9 @@ void* PhysicsBackend::CreateScene(const PhysicsSettings& settings)
|
|||||||
{
|
{
|
||||||
if (CpuDispatcher == nullptr)
|
if (CpuDispatcher == nullptr)
|
||||||
{
|
{
|
||||||
#if PLATFORM_THREADS_LIMIT > 1
|
|
||||||
uint32 threads = Math::Clamp<uint32>(Platform::GetCPUInfo().ProcessorCoreCount - 1, 1, 8);
|
uint32 threads = Math::Clamp<uint32>(Platform::GetCPUInfo().ProcessorCoreCount - 1, 1, 8);
|
||||||
CpuDispatcher = PxDefaultCpuDispatcherCreate(threads);
|
CpuDispatcher = PxDefaultCpuDispatcherCreate(threads);
|
||||||
CHECK_INIT(CpuDispatcher, "PxDefaultCpuDispatcherCreate failed!");
|
CHECK_INIT(CpuDispatcher, "PxDefaultCpuDispatcherCreate failed!");
|
||||||
#else
|
|
||||||
CpuDispatcher = New<DummyCpuDispatcher>();
|
|
||||||
#endif
|
|
||||||
CHECK_INIT(CpuDispatcher, "PxDefaultCpuDispatcherCreate failed!");
|
|
||||||
}
|
}
|
||||||
sceneDesc.cpuDispatcher = CpuDispatcher;
|
sceneDesc.cpuDispatcher = CpuDispatcher;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,12 +39,6 @@ public class Physics : EngineModule
|
|||||||
{
|
{
|
||||||
base.Setup(options);
|
base.Setup(options);
|
||||||
|
|
||||||
if (options.Platform.Target == TargetPlatform.Web) // TODO: build PhysX for Web
|
|
||||||
{
|
|
||||||
options.PrivateDefinitions.Add("COMPILE_WITH_EMPTY_PHYSICS");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetupPhysicsBackend(this, options);
|
SetupPhysicsBackend(this, options);
|
||||||
|
|
||||||
if (WithCooking)
|
if (WithCooking)
|
||||||
|
|||||||
@@ -99,6 +99,11 @@ public:
|
|||||||
static void Yield();
|
static void Yield();
|
||||||
static double GetTimeSeconds();
|
static double GetTimeSeconds();
|
||||||
static uint64 GetTimeCycles();
|
static uint64 GetTimeCycles();
|
||||||
|
FORCE_INLINE static uint64 GetClockFrequency()
|
||||||
|
{
|
||||||
|
// Dummy value
|
||||||
|
return 1000000;
|
||||||
|
}
|
||||||
static void GetSystemTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond);
|
static void GetSystemTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond);
|
||||||
static void GetUTCTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond);
|
static void GetUTCTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond);
|
||||||
static bool Init();
|
static bool Init();
|
||||||
|
|||||||
@@ -244,11 +244,11 @@ bool FileSystemBase::CopyDirectory(const String& dst, const String& src, bool wi
|
|||||||
return !FileSystem::DirectoryExists(*src) || FileSystemBase::DirectoryCopyHelper(dst, src, withSubDirectories);
|
return !FileSystem::DirectoryExists(*src) || FileSystemBase::DirectoryCopyHelper(dst, src, withSubDirectories);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 FileSystemBase::GetDirectorySize(const StringView& path, const Char* searchPattern, DirectorySearchOption option)
|
uint64 FileSystemBase::GetDirectorySize(const StringView& path)
|
||||||
{
|
{
|
||||||
uint64 result = 0;
|
uint64 result = 0;
|
||||||
Array<String> files;
|
Array<String> files;
|
||||||
FileSystem::DirectoryGetFiles(files, path, searchPattern, option);
|
FileSystem::DirectoryGetFiles(files, path);
|
||||||
for (const String& file : files)
|
for (const String& file : files)
|
||||||
result += FileSystem::GetFileSize(file);
|
result += FileSystem::GetFileSize(file);
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -98,10 +98,8 @@ class FLAXENGINE_API FileSystemBase
|
|||||||
/// Gets the size of the directory (in bytes) defined by size of all files contained by it.
|
/// Gets the size of the directory (in bytes) defined by size of all files contained by it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">Directory path.</param>
|
/// <param name="path">Directory path.</param>
|
||||||
/// <param name="searchPattern">Custom search pattern to use during that operation Use asterisk character (*) for name-based filtering (eg. `*.txt` to find all files with `.txt` extension).</param>
|
|
||||||
/// <param name="option">Additional search options that define rules.</param>
|
|
||||||
/// <returns>Amount of bytes in directory, or 0 if failed.</returns>
|
/// <returns>Amount of bytes in directory, or 0 if failed.</returns>
|
||||||
static uint64 GetDirectorySize(const StringView& path, const Char* searchPattern = TEXT("*"), DirectorySearchOption option = DirectorySearchOption::AllDirectories);
|
static uint64 GetDirectorySize(const StringView& path);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ static_assert(sizeof(double) == 8, "Invalid double type size.");
|
|||||||
|
|
||||||
// Check configuration
|
// Check configuration
|
||||||
static_assert((PLATFORM_THREADS_LIMIT & (PLATFORM_THREADS_LIMIT - 1)) == 0, "Threads limit must be power of two.");
|
static_assert((PLATFORM_THREADS_LIMIT & (PLATFORM_THREADS_LIMIT - 1)) == 0, "Threads limit must be power of two.");
|
||||||
static_assert(PLATFORM_THREADS_LIMIT % 4 == 0 || PLATFORM_THREADS_LIMIT == 1, "Threads limit must be multiple of 4.");
|
static_assert(PLATFORM_THREADS_LIMIT % 4 == 0, "Threads limit must be multiple of 4.");
|
||||||
|
|
||||||
const Char* PlatformBase::ApplicationClassName = TEXT("FlaxWindow");
|
const Char* PlatformBase::ApplicationClassName = TEXT("FlaxWindow");
|
||||||
float PlatformBase::CustomDpiScale = 1.0f;
|
float PlatformBase::CustomDpiScale = 1.0f;
|
||||||
@@ -301,15 +301,6 @@ bool PlatformBase::Is64BitApp()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PlatformBase::Is64BitPlatform()
|
|
||||||
{
|
|
||||||
#if PLATFORM_64BITS
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 PlatformBase::GetCacheLineSize()
|
int32 PlatformBase::GetCacheLineSize()
|
||||||
{
|
{
|
||||||
return (int32)Platform::GetCPUInfo().CacheLineSize;
|
return (int32)Platform::GetCPUInfo().CacheLineSize;
|
||||||
@@ -829,8 +820,6 @@ const Char* ToString(PlatformType type)
|
|||||||
return TEXT("Mac");
|
return TEXT("Mac");
|
||||||
case PlatformType::iOS:
|
case PlatformType::iOS:
|
||||||
return TEXT("iOS");
|
return TEXT("iOS");
|
||||||
case PlatformType::Web:
|
|
||||||
return TEXT("Web");
|
|
||||||
default:
|
default:
|
||||||
return TEXT("");
|
return TEXT("");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -378,7 +378,7 @@ public:
|
|||||||
/// Returns true if running on 64-bit computer
|
/// Returns true if running on 64-bit computer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if running on 64-bit computer, otherwise false.</returns>
|
/// <returns>True if running on 64-bit computer, otherwise false.</returns>
|
||||||
API_PROPERTY() static bool Is64BitPlatform();
|
API_PROPERTY() static bool Is64BitPlatform() = delete;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name of the operating system.
|
/// Gets the name of the operating system.
|
||||||
@@ -470,11 +470,7 @@ public:
|
|||||||
/// Gets the system clock frequency.
|
/// Gets the system clock frequency.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The clock frequency.</returns>
|
/// <returns>The clock frequency.</returns>
|
||||||
API_PROPERTY() static uint64 GetClockFrequency()
|
API_PROPERTY() static uint64 GetClockFrequency() = delete;
|
||||||
{
|
|
||||||
// Dummy value
|
|
||||||
return 1000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets current system time based on current computer settings.
|
/// Gets current system time based on current computer settings.
|
||||||
|
|||||||
@@ -357,8 +357,6 @@ StringView StringUtils::GetPathWithoutExtension(const StringView& path)
|
|||||||
void StringUtils::PathRemoveRelativeParts(String& path)
|
void StringUtils::PathRemoveRelativeParts(String& path)
|
||||||
{
|
{
|
||||||
FileSystem::NormalizePath(path);
|
FileSystem::NormalizePath(path);
|
||||||
if (path.Length() == 1 && path[0] == TEXT('/'))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Array<String> components;
|
Array<String> components;
|
||||||
path.Split(TEXT('/'), components);
|
path.Split(TEXT('/'), components);
|
||||||
|
|||||||
@@ -45,15 +45,10 @@ void ThreadBase::Kill(bool waitForJoin)
|
|||||||
if (!_isRunning)
|
if (!_isRunning)
|
||||||
{
|
{
|
||||||
ClearHandleInternal();
|
ClearHandleInternal();
|
||||||
if (_callAfterWork)
|
|
||||||
{
|
|
||||||
_callAfterWork = false;
|
|
||||||
_runnable->AfterWork(true);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ASSERT(GetID());
|
ASSERT(GetID());
|
||||||
Thread* thread = (Thread*)this;
|
const auto thread = static_cast<Thread*>(this);
|
||||||
|
|
||||||
// Stop runnable object
|
// Stop runnable object
|
||||||
if (_callAfterWork && _runnable)
|
if (_callAfterWork && _runnable)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#if PLATFORM_WINDOWS || PLATFORM_UWP || PLATFORM_XBOX_ONE || PLATFORM_XBOX_SCARLETT
|
#if PLATFORM_WINDOWS || PLATFORM_UWP || PLATFORM_XBOX_ONE || PLATFORM_XBOX_SCARLETT
|
||||||
#include "Win32/Win32ConditionVariable.h"
|
#include "Win32/Win32ConditionVariable.h"
|
||||||
#elif PLATFORM_LINUX || PLATFORM_ANDROID || PLATFORM_PS4 || PLATFORM_PS5 || PLATFORM_MAC || PLATFORM_IOS || PLATFORM_WEB
|
#elif PLATFORM_LINUX || PLATFORM_ANDROID || PLATFORM_PS4 || PLATFORM_PS5 || PLATFORM_MAC || PLATFORM_IOS
|
||||||
#include "Unix/UnixConditionVariable.h"
|
#include "Unix/UnixConditionVariable.h"
|
||||||
#elif PLATFORM_SWITCH
|
#elif PLATFORM_SWITCH
|
||||||
#include "Platforms/Switch/Engine/Platform/SwitchConditionVariable.h"
|
#include "Platforms/Switch/Engine/Platform/SwitchConditionVariable.h"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#if PLATFORM_WINDOWS || PLATFORM_UWP || PLATFORM_XBOX_ONE || PLATFORM_XBOX_SCARLETT
|
#if PLATFORM_WINDOWS || PLATFORM_UWP || PLATFORM_XBOX_ONE || PLATFORM_XBOX_SCARLETT
|
||||||
#include "Win32/Win32CriticalSection.h"
|
#include "Win32/Win32CriticalSection.h"
|
||||||
#elif PLATFORM_LINUX || PLATFORM_ANDROID || PLATFORM_PS4 || PLATFORM_PS5 || PLATFORM_MAC || PLATFORM_IOS || PLATFORM_WEB
|
#elif PLATFORM_LINUX || PLATFORM_ANDROID || PLATFORM_PS4 || PLATFORM_PS5 || PLATFORM_MAC || PLATFORM_IOS
|
||||||
#include "Unix/UnixCriticalSection.h"
|
#include "Unix/UnixCriticalSection.h"
|
||||||
#elif PLATFORM_SWITCH
|
#elif PLATFORM_SWITCH
|
||||||
#include "Platforms/Switch/Engine/Platform/SwitchCriticalSection.h"
|
#include "Platforms/Switch/Engine/Platform/SwitchCriticalSection.h"
|
||||||
|
|||||||
@@ -67,11 +67,6 @@ API_ENUM() enum class PlatformType
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
API_ENUM(Attributes="EditorDisplay(null, \"iOS\")")
|
API_ENUM(Attributes="EditorDisplay(null, \"iOS\")")
|
||||||
iOS = 11,
|
iOS = 11,
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Running on Web.
|
|
||||||
/// </summary>
|
|
||||||
Web = 12,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -148,9 +143,6 @@ API_ENUM() enum class ArchitectureType
|
|||||||
#if !defined(PLATFORM_SDL)
|
#if !defined(PLATFORM_SDL)
|
||||||
#define PLATFORM_SDL 0
|
#define PLATFORM_SDL 0
|
||||||
#endif
|
#endif
|
||||||
#if !defined(PLATFORM_WEB)
|
|
||||||
#define PLATFORM_WEB 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PLATFORM_WINDOWS
|
#if PLATFORM_WINDOWS
|
||||||
#include "Windows/WindowsDefines.h"
|
#include "Windows/WindowsDefines.h"
|
||||||
@@ -174,8 +166,6 @@ API_ENUM() enum class ArchitectureType
|
|||||||
#include "Mac/MacDefines.h"
|
#include "Mac/MacDefines.h"
|
||||||
#elif PLATFORM_IOS
|
#elif PLATFORM_IOS
|
||||||
#include "iOS/iOSDefines.h"
|
#include "iOS/iOSDefines.h"
|
||||||
#elif PLATFORM_WEB
|
|
||||||
#include "Web/WebDefines.h"
|
|
||||||
#else
|
#else
|
||||||
#error Missing Defines implementation!
|
#error Missing Defines implementation!
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#if PLATFORM_WINDOWS || PLATFORM_UWP || PLATFORM_XBOX_ONE || PLATFORM_XBOX_SCARLETT
|
#if PLATFORM_WINDOWS || PLATFORM_UWP || PLATFORM_XBOX_ONE || PLATFORM_XBOX_SCARLETT
|
||||||
#include "Win32/Win32File.h"
|
#include "Win32/Win32File.h"
|
||||||
#elif PLATFORM_LINUX || PLATFORM_PS4 || PLATFORM_PS5 || PLATFORM_MAC || PLATFORM_WEB
|
#elif PLATFORM_LINUX || PLATFORM_PS4 || PLATFORM_PS5 || PLATFORM_MAC
|
||||||
#include "Unix/UnixFile.h"
|
#include "Unix/UnixFile.h"
|
||||||
#elif PLATFORM_IOS
|
#elif PLATFORM_IOS
|
||||||
#include "iOS/iOSFile.h"
|
#include "iOS/iOSFile.h"
|
||||||
|
|||||||
@@ -24,8 +24,6 @@
|
|||||||
#include "Mac/MacFileSystem.h"
|
#include "Mac/MacFileSystem.h"
|
||||||
#elif PLATFORM_IOS
|
#elif PLATFORM_IOS
|
||||||
#include "iOS/iOSFileSystem.h"
|
#include "iOS/iOSFileSystem.h"
|
||||||
#elif PLATFORM_WEB
|
|
||||||
#include "Web/WebFileSystem.h"
|
|
||||||
#else
|
#else
|
||||||
#error Missing File System implementation!
|
#error Missing File System implementation!
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -114,6 +114,11 @@ public:
|
|||||||
static void Yield();
|
static void Yield();
|
||||||
static double GetTimeSeconds();
|
static double GetTimeSeconds();
|
||||||
static uint64 GetTimeCycles();
|
static uint64 GetTimeCycles();
|
||||||
|
FORCE_INLINE static uint64 GetClockFrequency()
|
||||||
|
{
|
||||||
|
// Dummy value
|
||||||
|
return 1000000;
|
||||||
|
}
|
||||||
static void GetSystemTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond);
|
static void GetSystemTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond);
|
||||||
static void GetUTCTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond);
|
static void GetUTCTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond);
|
||||||
#if !BUILD_RELEASE
|
#if !BUILD_RELEASE
|
||||||
|
|||||||
1153
Source/Engine/Platform/Mac/MacWindow.DragDrop.cpp
Normal file
1153
Source/Engine/Platform/Mac/MacWindow.DragDrop.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#if PLATFORM_WINDOWS || PLATFORM_UWP || PLATFORM_XBOX_ONE || PLATFORM_XBOX_SCARLETT
|
#if PLATFORM_WINDOWS || PLATFORM_UWP || PLATFORM_XBOX_ONE || PLATFORM_XBOX_SCARLETT
|
||||||
#include "Win32/Win32Network.h"
|
#include "Win32/Win32Network.h"
|
||||||
#elif PLATFORM_LINUX || PLATFORM_ANDROID || PLATFORM_MAC || PLATFORM_IOS || PLATFORM_WEB
|
#elif PLATFORM_LINUX || PLATFORM_ANDROID || PLATFORM_MAC || PLATFORM_IOS
|
||||||
#include "Unix/UnixNetwork.h"
|
#include "Unix/UnixNetwork.h"
|
||||||
#elif PLATFORM_PS4
|
#elif PLATFORM_PS4
|
||||||
#include "Platforms/PS4/Engine/Platform/PS4Network.h"
|
#include "Platforms/PS4/Engine/Platform/PS4Network.h"
|
||||||
|
|||||||
@@ -87,17 +87,20 @@ public class Platform : EngineModule
|
|||||||
options.SourcePaths.Add(Path.Combine(FolderPath, "Apple"));
|
options.SourcePaths.Add(Path.Combine(FolderPath, "Apple"));
|
||||||
options.SourcePaths.Add(Path.Combine(FolderPath, "iOS"));
|
options.SourcePaths.Add(Path.Combine(FolderPath, "iOS"));
|
||||||
break;
|
break;
|
||||||
case TargetPlatform.Web:
|
|
||||||
options.SourcePaths.Add(Path.Combine(FolderPath, "Unix"));
|
|
||||||
options.SourcePaths.Add(Path.Combine(FolderPath, "Web"));
|
|
||||||
break;
|
|
||||||
default: throw new InvalidPlatformException(options.Platform.Target);
|
default: throw new InvalidPlatformException(options.Platform.Target);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EngineConfiguration.WithSDL(options))
|
if (EngineConfiguration.WithSDL(options))
|
||||||
{
|
{
|
||||||
options.PublicDependencies.Add("SDL");
|
switch (options.Platform.Target)
|
||||||
options.SourcePaths.Add(Path.Combine(FolderPath, "SDL"));
|
{
|
||||||
|
case TargetPlatform.Windows:
|
||||||
|
case TargetPlatform.Linux:
|
||||||
|
case TargetPlatform.Mac:
|
||||||
|
options.PublicDependencies.Add("SDL");
|
||||||
|
options.SourcePaths.Add(Path.Combine(FolderPath, "SDL"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (options.Platform.Target == TargetPlatform.Linux)
|
if (options.Platform.Target == TargetPlatform.Linux)
|
||||||
options.PublicDependencies.Add("Wayland");
|
options.PublicDependencies.Add("Wayland");
|
||||||
}
|
}
|
||||||
@@ -112,7 +115,6 @@ public class Platform : EngineModule
|
|||||||
options.SourceFiles.Add(Path.Combine(FolderPath, "Apple", "ApplePlatformSettings.h"));
|
options.SourceFiles.Add(Path.Combine(FolderPath, "Apple", "ApplePlatformSettings.h"));
|
||||||
options.SourceFiles.Add(Path.Combine(FolderPath, "Mac", "MacPlatformSettings.h"));
|
options.SourceFiles.Add(Path.Combine(FolderPath, "Mac", "MacPlatformSettings.h"));
|
||||||
options.SourceFiles.Add(Path.Combine(FolderPath, "iOS", "iOSPlatformSettings.h"));
|
options.SourceFiles.Add(Path.Combine(FolderPath, "iOS", "iOSPlatformSettings.h"));
|
||||||
options.SourceFiles.Add(Path.Combine(FolderPath, "Web", "WebPlatformSettings.h"));
|
|
||||||
AddSourceFileIfExists(options, Path.Combine(Globals.EngineRoot, "Source", "Platforms", "XboxOne", "Engine", "Platform", "XboxOnePlatformSettings.h"));
|
AddSourceFileIfExists(options, Path.Combine(Globals.EngineRoot, "Source", "Platforms", "XboxOne", "Engine", "Platform", "XboxOnePlatformSettings.h"));
|
||||||
AddSourceFileIfExists(options, Path.Combine(Globals.EngineRoot, "Source", "Platforms", "XboxScarlett", "Engine", "Platform", "XboxScarlettPlatformSettings.h"));
|
AddSourceFileIfExists(options, Path.Combine(Globals.EngineRoot, "Source", "Platforms", "XboxScarlett", "Engine", "Platform", "XboxScarlettPlatformSettings.h"));
|
||||||
AddSourceFileIfExists(options, Path.Combine(Globals.EngineRoot, "Source", "Platforms", "PS4", "Engine", "Platform", "PS4PlatformSettings.h"));
|
AddSourceFileIfExists(options, Path.Combine(Globals.EngineRoot, "Source", "Platforms", "PS4", "Engine", "Platform", "PS4PlatformSettings.h"));
|
||||||
|
|||||||
@@ -32,8 +32,6 @@
|
|||||||
#include "Mac/MacPlatform.h"
|
#include "Mac/MacPlatform.h"
|
||||||
#elif PLATFORM_IOS
|
#elif PLATFORM_IOS
|
||||||
#include "iOS/iOSPlatform.h"
|
#include "iOS/iOSPlatform.h"
|
||||||
#elif PLATFORM_WEB
|
|
||||||
#include "Web/WebPlatform.h"
|
|
||||||
#else
|
#else
|
||||||
#error Missing Platform implementation!
|
#error Missing Platform implementation!
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#if PLATFORM_WINDOWS || PLATFORM_UWP || PLATFORM_XBOX_ONE || PLATFORM_XBOX_SCARLETT
|
#if PLATFORM_WINDOWS || PLATFORM_UWP || PLATFORM_XBOX_ONE || PLATFORM_XBOX_SCARLETT
|
||||||
#include "Win32/Win32ReadWriteLock.h"
|
#include "Win32/Win32ReadWriteLock.h"
|
||||||
#elif PLATFORM_LINUX || PLATFORM_ANDROID || PLATFORM_PS4 || PLATFORM_PS5 || PLATFORM_MAC || PLATFORM_IOS || PLATFORM_WEB
|
#elif PLATFORM_LINUX || PLATFORM_ANDROID || PLATFORM_PS4 || PLATFORM_PS5 || PLATFORM_MAC || PLATFORM_IOS
|
||||||
#include "Unix/UnixReadWriteLock.h"
|
#include "Unix/UnixReadWriteLock.h"
|
||||||
#elif PLATFORM_SWITCH
|
#elif PLATFORM_SWITCH
|
||||||
#include "Platforms/Switch/Engine/Platform/SwitchReadWriteLock.h"
|
#include "Platforms/Switch/Engine/Platform/SwitchReadWriteLock.h"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
|
#include "SDLInput.h"
|
||||||
#if PLATFORM_SDL && PLATFORM_MAC
|
#if PLATFORM_SDL && PLATFORM_MAC
|
||||||
|
|
||||||
#include "SDLWindow.h"
|
#include "SDLWindow.h"
|
||||||
@@ -20,7 +21,10 @@
|
|||||||
#include "Engine/Platform/Unix/UnixFile.h"
|
#include "Engine/Platform/Unix/UnixFile.h"
|
||||||
#include "Engine/Profiler/ProfilerCPU.h"
|
#include "Engine/Profiler/ProfilerCPU.h"
|
||||||
|
|
||||||
#include "Engine/Platform/Linux/IncludeX11.h"
|
#include "Engine/Platform/Apple/AppleUtils.h"
|
||||||
|
#include <Cocoa/Cocoa.h>
|
||||||
|
#include <AppKit/AppKit.h>
|
||||||
|
#include <QuartzCore/CAMetalLayer.h>
|
||||||
|
|
||||||
#include <SDL3/SDL_events.h>
|
#include <SDL3/SDL_events.h>
|
||||||
#include <SDL3/SDL_hints.h>
|
#include <SDL3/SDL_hints.h>
|
||||||
@@ -30,6 +34,43 @@
|
|||||||
#include <SDL3/SDL_timer.h>
|
#include <SDL3/SDL_timer.h>
|
||||||
#include <SDL3/SDL_video.h>
|
#include <SDL3/SDL_video.h>
|
||||||
|
|
||||||
|
namespace MacImpl
|
||||||
|
{
|
||||||
|
Window* DraggedWindow = nullptr;
|
||||||
|
String DraggingData = String();
|
||||||
|
Float2 DraggingPosition;
|
||||||
|
Nullable<Float2> LastMouseDragPosition;
|
||||||
|
#if USE_EDITOR
|
||||||
|
//CriticalSection MacDragLocker;
|
||||||
|
bool DraggingActive = false;
|
||||||
|
bool DraggingIgnoreEvent = false;
|
||||||
|
NSDraggingSession* MacDragSession = nullptr;
|
||||||
|
//DoDragDropJob* MacDragJob = nullptr;
|
||||||
|
int64 MacDragExitFlag = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
class MacDropData : public IGuiData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Type CurrentType;
|
||||||
|
String AsText;
|
||||||
|
Array<String> AsFiles;
|
||||||
|
|
||||||
|
Type GetType() const override
|
||||||
|
{
|
||||||
|
return CurrentType;
|
||||||
|
}
|
||||||
|
String GetAsText() const override
|
||||||
|
{
|
||||||
|
return AsText;
|
||||||
|
}
|
||||||
|
void GetAsFiles(Array<String>* files) const override
|
||||||
|
{
|
||||||
|
files->Add(AsFiles);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
bool SDLPlatform::InitInternal()
|
bool SDLPlatform::InitInternal()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -50,16 +91,282 @@ bool SDLPlatform::UsesX11()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SDLPlatform::EventFilterCallback(void* userdata, SDL_Event* event)
|
||||||
|
{
|
||||||
|
Window* draggedWindow = *(Window**)userdata;
|
||||||
|
if (draggedWindow == nullptr)
|
||||||
|
{
|
||||||
|
if (MacImpl::DraggingActive)
|
||||||
|
{
|
||||||
|
// Handle events during drag operation here since the normal event loop is blocked
|
||||||
|
if (event->type == SDL_EVENT_WINDOW_EXPOSED)
|
||||||
|
{
|
||||||
|
LOG(Info, "Window exposed event");
|
||||||
|
// The internal timer is sending exposed events every ~16ms
|
||||||
|
#if USE_EDITOR
|
||||||
|
// Flush any single-frame shapes to prevent memory leaking (eg. via terrain collision debug during scene drawing with PhysicsColliders or PhysicsDebug flag)
|
||||||
|
DebugDraw::UpdateContext(nullptr, 0.0f);
|
||||||
|
#endif
|
||||||
|
Engine::OnUpdate(); // For docking updates
|
||||||
|
Engine::OnDraw();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SDLWindow* window = SDLWindow::GetWindowFromEvent(*event);
|
||||||
|
if (window)
|
||||||
|
window->HandleEvent(*event);
|
||||||
|
|
||||||
|
// We do not receive events at steady rate to keep the engine updated...
|
||||||
|
#if USE_EDITOR
|
||||||
|
// Flush any single-frame shapes to prevent memory leaking (eg. via terrain collision debug during scene drawing with PhysicsColliders or PhysicsDebug flag)
|
||||||
|
DebugDraw::UpdateContext(nullptr, 0.0f);
|
||||||
|
#endif
|
||||||
|
Engine::OnUpdate(); // For docking updates
|
||||||
|
Engine::OnDraw();
|
||||||
|
|
||||||
|
if (event->type == SDL_EVENT_DROP_BEGIN || event->type == SDL_EVENT_DROP_FILE || event->type == SDL_EVENT_DROP_TEXT)
|
||||||
|
return true; // Filtering these event stops other following events from getting added to the queue
|
||||||
|
else
|
||||||
|
LOG(Info, "Unhandled event: {}", event->type);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// When the window is being dragged on Windows, the internal message loop is blocking
|
||||||
|
// the SDL event queue. We need to handle all relevant events in this event watch callback
|
||||||
|
// to ensure dragging related functionality doesn't break due to engine not getting updated.
|
||||||
|
// This also happens to fix the engine freezing during the dragging operation.
|
||||||
|
#if false
|
||||||
|
SDLWindow* window = SDLWindow::GetWindowFromEvent(*event);
|
||||||
|
if (event->type == SDL_EVENT_WINDOW_EXPOSED)
|
||||||
|
{
|
||||||
|
// The internal timer is sending exposed events every ~16ms
|
||||||
|
Engine::OnUpdate(); // For docking updates
|
||||||
|
Engine::OnDraw();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (event->type == SDL_EVENT_MOUSE_BUTTON_DOWN)
|
||||||
|
{
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
window->OnLeftButtonHit(WindowHitCodes::Caption, result);
|
||||||
|
//if (result)
|
||||||
|
// return false;
|
||||||
|
window->HandleEvent(*event);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (event->type == SDL_EVENT_WINDOW_MOVED)
|
||||||
|
{
|
||||||
|
if (window)
|
||||||
|
window->HandleEvent(*event);
|
||||||
|
|
||||||
|
/*if (WinImpl::DraggedWindowSize != window->GetClientSize())
|
||||||
|
{
|
||||||
|
// The window size changed while dragging, most likely due to maximized window restoring back to previous size.
|
||||||
|
WinImpl::DraggedWindowMousePosition = WinImpl::DraggedWindowStartPosition + WinImpl::DraggedWindowMousePosition - window->GetClientPosition();
|
||||||
|
WinImpl::DraggedWindowStartPosition = window->GetClientPosition();
|
||||||
|
WinImpl::DraggedWindowSize = window->GetClientSize();
|
||||||
|
}
|
||||||
|
Float2 windowPosition = Float2(static_cast<float>(event->window.data1), static_cast<float>(event->window.data2));
|
||||||
|
Float2 mousePosition = WinImpl::DraggedWindowMousePosition;
|
||||||
|
|
||||||
|
// Generate mouse movement events while dragging the window around
|
||||||
|
SDL_Event mouseMovedEvent { 0 };
|
||||||
|
mouseMovedEvent.motion.type = SDL_EVENT_MOUSE_MOTION;
|
||||||
|
mouseMovedEvent.motion.windowID = SDL_GetWindowID(WinImpl::DraggedWindow->GetSDLWindow());
|
||||||
|
mouseMovedEvent.motion.timestamp = SDL_GetTicksNS();
|
||||||
|
mouseMovedEvent.motion.state = SDL_BUTTON_LEFT;
|
||||||
|
mouseMovedEvent.motion.x = mousePosition.X;
|
||||||
|
mouseMovedEvent.motion.y = mousePosition.Y;
|
||||||
|
if (window)
|
||||||
|
window->HandleEvent(mouseMovedEvent);*/
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (window)
|
||||||
|
window->HandleEvent(*event);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void SDLPlatform::PreHandleEvents()
|
void SDLPlatform::PreHandleEvents()
|
||||||
{
|
{
|
||||||
|
SDL_SetEventFilter(EventFilterCallback, &MacImpl::DraggedWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDLPlatform::PostHandleEvents()
|
void SDLPlatform::PostHandleEvents()
|
||||||
{
|
{
|
||||||
|
SDL_SetEventFilter(EventFilterCallback, &MacImpl::DraggedWindow);
|
||||||
|
|
||||||
|
// Handle window dragging release here
|
||||||
|
if (MacImpl::DraggedWindow != nullptr)
|
||||||
|
{
|
||||||
|
Float2 mousePosition;
|
||||||
|
auto buttons = SDL_GetGlobalMouseState(&mousePosition.X, &mousePosition.Y);
|
||||||
|
bool buttonReleased = (buttons & SDL_BUTTON_MASK(SDL_BUTTON_LEFT)) == 0;
|
||||||
|
if (buttonReleased)
|
||||||
|
{
|
||||||
|
// Send simulated mouse up event
|
||||||
|
SDL_Event buttonUpEvent { 0 };
|
||||||
|
buttonUpEvent.motion.type = SDL_EVENT_MOUSE_BUTTON_UP;
|
||||||
|
buttonUpEvent.button.down = false;
|
||||||
|
buttonUpEvent.motion.windowID = SDL_GetWindowID(MacImpl::DraggedWindow->GetSDLWindow());
|
||||||
|
buttonUpEvent.motion.timestamp = SDL_GetTicksNS();
|
||||||
|
buttonUpEvent.motion.state = SDL_BUTTON_LEFT;
|
||||||
|
buttonUpEvent.button.clicks = 1;
|
||||||
|
buttonUpEvent.motion.x = mousePosition.X;
|
||||||
|
buttonUpEvent.motion.y = mousePosition.Y;
|
||||||
|
MacImpl::DraggedWindow->HandleEvent(buttonUpEvent);
|
||||||
|
MacImpl::DraggedWindow = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SDLWindow::HandleEventInternal(SDL_Event& event)
|
bool SDLWindow::HandleEventInternal(SDL_Event& event)
|
||||||
{
|
{
|
||||||
|
switch (event.type)
|
||||||
|
{
|
||||||
|
case SDL_EVENT_WINDOW_MOVED:
|
||||||
|
{
|
||||||
|
// Quartz doesn't report any mouse events when mouse is over the caption area, send a simulated event instead...
|
||||||
|
Float2 mousePosition;
|
||||||
|
auto buttons = SDL_GetGlobalMouseState(&mousePosition.X, &mousePosition.Y);
|
||||||
|
if ((buttons & SDL_BUTTON_MASK(SDL_BUTTON_LEFT)) != 0)
|
||||||
|
{
|
||||||
|
if (MacImpl::DraggedWindow == nullptr)
|
||||||
|
{
|
||||||
|
// TODO: verify mouse position, window focus
|
||||||
|
bool result = false;
|
||||||
|
OnLeftButtonHit(WindowHitCodes::Caption, result);
|
||||||
|
if (result)
|
||||||
|
MacImpl::DraggedWindow = this;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Float2 mousePos = Platform::GetMousePosition();
|
||||||
|
Input::Mouse->OnMouseMove(mousePos, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||||
|
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||||
|
{
|
||||||
|
if (MacImpl::LastMouseDragPosition.HasValue())
|
||||||
|
{
|
||||||
|
// SDL reports wrong mouse position after dragging has ended
|
||||||
|
Float2 mouseClientPosition = ScreenToClient(MacImpl::LastMouseDragPosition.GetValue());
|
||||||
|
event.button.x = mouseClientPosition.X;
|
||||||
|
event.button.y = mouseClientPosition.Y;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_EVENT_MOUSE_MOTION:
|
||||||
|
{
|
||||||
|
if (MacImpl::LastMouseDragPosition.HasValue())
|
||||||
|
MacImpl::LastMouseDragPosition.Reset();
|
||||||
|
if (MacImpl::DraggedWindow != nullptr)
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
|
||||||
|
{
|
||||||
|
OnDragLeave(); // Check for release of mouse button too?
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//case SDL_EVENT_CLIPBOARD_UPDATE:
|
||||||
|
case SDL_EVENT_DROP_BEGIN:
|
||||||
|
case SDL_EVENT_DROP_POSITION:
|
||||||
|
case SDL_EVENT_DROP_FILE:
|
||||||
|
case SDL_EVENT_DROP_TEXT:
|
||||||
|
case SDL_EVENT_DROP_COMPLETE:
|
||||||
|
{
|
||||||
|
{
|
||||||
|
// HACK: We can't use Wayland listeners due to SDL also using them at the same time causes
|
||||||
|
// some of the events to drop and make it impossible to implement dragging on application side.
|
||||||
|
// We can get enough information through SDL_EVENT_DROP_* events to fill in the blanks for the
|
||||||
|
// drag and drop implementation.
|
||||||
|
|
||||||
|
auto dpiScale = GetDpiScale();
|
||||||
|
Float2 mousePos = Float2(event.drop.x * dpiScale, event.drop.y * dpiScale);
|
||||||
|
DragDropEffect effect = DragDropEffect::None;
|
||||||
|
String text(event.drop.data);
|
||||||
|
MacDropData dropData;
|
||||||
|
|
||||||
|
if (MacImpl::DraggingActive)
|
||||||
|
{
|
||||||
|
// We don't have the window dragging data during these events...
|
||||||
|
text = MacImpl::DraggingData;
|
||||||
|
mousePos = ScreenToClient(MacImpl::DraggingPosition);
|
||||||
|
|
||||||
|
// Ensure mouse position is updated while dragging
|
||||||
|
Input::Mouse->OnMouseMove(MacImpl::DraggingPosition, this);
|
||||||
|
MacImpl::LastMouseDragPosition = MacImpl::DraggingPosition;
|
||||||
|
}
|
||||||
|
dropData.AsText = text;
|
||||||
|
|
||||||
|
if (event.type == SDL_EVENT_DROP_BEGIN)
|
||||||
|
{
|
||||||
|
// We don't know the type of dragged data at this point, so call the events for both types
|
||||||
|
if (!MacImpl::DraggingActive)
|
||||||
|
{
|
||||||
|
dropData.CurrentType = IGuiData::Type::Files;
|
||||||
|
OnDragEnter(&dropData, mousePos, effect);
|
||||||
|
}
|
||||||
|
if (effect == DragDropEffect::None)
|
||||||
|
{
|
||||||
|
dropData.CurrentType = IGuiData::Type::Text;
|
||||||
|
OnDragEnter(&dropData, mousePos, effect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (event.type == SDL_EVENT_DROP_POSITION)
|
||||||
|
{
|
||||||
|
Input::Mouse->OnMouseMove(ClientToScreen(mousePos), this);
|
||||||
|
|
||||||
|
// We don't know the type of dragged data at this point, so call the events for both types
|
||||||
|
if (!MacImpl::DraggingActive)
|
||||||
|
{
|
||||||
|
dropData.CurrentType = IGuiData::Type::Files;
|
||||||
|
OnDragOver(&dropData, mousePos, effect);
|
||||||
|
}
|
||||||
|
if (effect == DragDropEffect::None)
|
||||||
|
{
|
||||||
|
dropData.CurrentType = IGuiData::Type::Text;
|
||||||
|
OnDragOver(&dropData, mousePos, effect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (event.type == SDL_EVENT_DROP_FILE)
|
||||||
|
{
|
||||||
|
text.Split('\n', dropData.AsFiles);
|
||||||
|
dropData.CurrentType = IGuiData::Type::Files;
|
||||||
|
OnDragDrop(&dropData, mousePos, effect);
|
||||||
|
}
|
||||||
|
else if (event.type == SDL_EVENT_DROP_TEXT)
|
||||||
|
{
|
||||||
|
dropData.CurrentType = IGuiData::Type::Text;
|
||||||
|
OnDragDrop(&dropData, mousePos, effect);
|
||||||
|
}
|
||||||
|
else if (event.type == SDL_EVENT_DROP_COMPLETE)
|
||||||
|
{
|
||||||
|
OnDragLeave();
|
||||||
|
if (MacImpl::DraggingActive)
|
||||||
|
{
|
||||||
|
// The previous drop events needs to be flushed to avoid processing them twice
|
||||||
|
SDL_FlushEvents(SDL_EVENT_DROP_FILE, SDL_EVENT_DROP_POSITION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Implement handling for feedback effect result (https://github.com/libsdl-org/SDL/issues/10448)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,9 +375,207 @@ void SDLPlatform::SetHighDpiAwarenessEnabled(bool enable)
|
|||||||
// TODO: This is now called before Platform::Init, ensure the scaling is changed accordingly during Platform::Init (see ApplePlatform::SetHighDpiAwarenessEnabled)
|
// TODO: This is now called before Platform::Init, ensure the scaling is changed accordingly during Platform::Init (see ApplePlatform::SetHighDpiAwarenessEnabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool IsWindowInvalid(Window* win)
|
||||||
|
{
|
||||||
|
WindowsManager::WindowsLocker.Lock();
|
||||||
|
const bool hasWindow = WindowsManager::Windows.Contains(win);
|
||||||
|
WindowsManager::WindowsLocker.Unlock();
|
||||||
|
return !hasWindow || !win;
|
||||||
|
}
|
||||||
|
|
||||||
|
Float2 GetWindowTitleSize(const SDLWindow* window)
|
||||||
|
{
|
||||||
|
Float2 size = Float2::Zero;
|
||||||
|
if (window->GetSettings().HasBorder)
|
||||||
|
{
|
||||||
|
NSRect frameStart = [(NSWindow*)window->GetNativePtr() frameRectForContentRect:NSMakeRect(0, 0, 0, 0)];
|
||||||
|
size.Y = frameStart.size.height;
|
||||||
|
}
|
||||||
|
return size * MacPlatform::ScreenScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
Float2 GetMousePosition(SDLWindow* window, NSEvent* event)
|
||||||
|
{
|
||||||
|
NSRect frame = [(NSWindow*)window->GetNativePtr() frame];
|
||||||
|
NSPoint point = [event locationInWindow];
|
||||||
|
return Float2(point.x, frame.size.height - point.y) * MacPlatform::ScreenScale - GetWindowTitleSize(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
Float2 GetMousePosition(SDLWindow* window, const NSPoint& point)
|
||||||
|
{
|
||||||
|
NSRect frame = [(NSWindow*)window->GetNativePtr() frame];
|
||||||
|
CGRect screenBounds = CGDisplayBounds(CGMainDisplayID());
|
||||||
|
return Float2(point.x, screenBounds.size.height - point.y) * MacPlatform::ScreenScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetDragDropData(const SDLWindow* window, id<NSDraggingInfo> sender, Float2& mousePos, MacDropData& dropData)
|
||||||
|
{
|
||||||
|
NSRect frame = [(NSWindow*)window->GetNativePtr() frame];
|
||||||
|
NSPoint point = [sender draggingLocation];
|
||||||
|
mousePos = Float2(point.x, frame.size.height - point.y) * MacPlatform::ScreenScale - GetWindowTitleSize(window);
|
||||||
|
NSPasteboard* pasteboard = [sender draggingPasteboard];
|
||||||
|
if ([[pasteboard types] containsObject:NSPasteboardTypeString])
|
||||||
|
{
|
||||||
|
dropData.CurrentType = IGuiData::Type::Text;
|
||||||
|
dropData.AsText = AppleUtils::ToString((CFStringRef)[pasteboard stringForType:NSPasteboardTypeString]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dropData.CurrentType = IGuiData::Type::Files;
|
||||||
|
NSArray* files = [pasteboard readObjectsForClasses:@[[NSURL class]] options:nil];
|
||||||
|
for (int32 i = 0; i < [files count]; i++)
|
||||||
|
{
|
||||||
|
NSString* url = [[files objectAtIndex:i] path];
|
||||||
|
NSString* file = [NSURL URLWithString:url].path;
|
||||||
|
dropData.AsFiles.Add(AppleUtils::ToString((CFStringRef)file));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NSDragOperation GetDragDropOperation(DragDropEffect dragDropEffect)
|
||||||
|
{
|
||||||
|
NSDragOperation result = NSDragOperationCopy;
|
||||||
|
switch (dragDropEffect)
|
||||||
|
{
|
||||||
|
case DragDropEffect::None:
|
||||||
|
//result = NSDragOperationNone;
|
||||||
|
break;
|
||||||
|
case DragDropEffect::Copy:
|
||||||
|
result = NSDragOperationCopy;
|
||||||
|
break;
|
||||||
|
case DragDropEffect::Move:
|
||||||
|
result = NSDragOperationMove;
|
||||||
|
break;
|
||||||
|
case DragDropEffect::Link:
|
||||||
|
result = NSDragOperationLink;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef INCLUDED_IN_SDL
|
||||||
|
|
||||||
|
|
||||||
|
@interface ClipboardDataProviderImpl : NSObject <NSPasteboardItemDataProvider, NSDraggingSource>
|
||||||
|
{
|
||||||
|
@public
|
||||||
|
SDLWindow* Window;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation ClipboardDataProviderImpl
|
||||||
|
|
||||||
|
// NSPasteboardItemDataProvider
|
||||||
|
// ---
|
||||||
|
|
||||||
|
- (void)pasteboard:(nullable NSPasteboard*)pasteboard item:(NSPasteboardItem*)item provideDataForType:(NSPasteboardType)type
|
||||||
|
{
|
||||||
|
LOG(Info, "pasteboard");
|
||||||
|
if (IsWindowInvalid(Window)) return;
|
||||||
|
[pasteboard setString:(NSString*)AppleUtils::ToString(MacImpl::DraggingData) forType:NSPasteboardTypeString];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)pasteboardFinishedWithDataProvider:(NSPasteboard*)pasteboard
|
||||||
|
{
|
||||||
|
LOG(Info, "pasteboardFinishedWithDataProvider");
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSDraggingSource
|
||||||
|
// ---
|
||||||
|
|
||||||
|
- (NSDragOperation)draggingSession:(NSDraggingSession*)session sourceOperationMaskForDraggingContext:(NSDraggingContext)context
|
||||||
|
{
|
||||||
|
if (IsWindowInvalid(Window))
|
||||||
|
return NSDragOperationNone;
|
||||||
|
|
||||||
|
switch(context)
|
||||||
|
{
|
||||||
|
case NSDraggingContextOutsideApplication:
|
||||||
|
LOG(Info, "draggingSession sourceOperationMaskForDraggingContext: outside");
|
||||||
|
return NSDragOperationCopy;
|
||||||
|
case NSDraggingContextWithinApplication:
|
||||||
|
LOG(Info, "draggingSession sourceOperationMaskForDraggingContext: inside");
|
||||||
|
return NSDragOperationCopy;
|
||||||
|
default:
|
||||||
|
LOG(Info, "draggingSession sourceOperationMaskForDraggingContext: unknown");
|
||||||
|
return NSDragOperationMove;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)draggingSession:(NSDraggingSession*)session willBeginAtPoint:(NSPoint)screenPoint
|
||||||
|
{
|
||||||
|
LOG(Info, "draggingSession willBeginAtPoint");
|
||||||
|
MacImpl::DraggingPosition = GetMousePosition(Window, screenPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)draggingSession:(NSDraggingSession*)session movedToPoint:(NSPoint)screenPoint
|
||||||
|
{
|
||||||
|
//LOG(Info, "draggingSession movedToPoint");
|
||||||
|
MacImpl::DraggingPosition = GetMousePosition(Window, screenPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)draggingSession:(NSDraggingSession*)session endedAtPoint:(NSPoint)screenPoint operation:(NSDragOperation)operation
|
||||||
|
{
|
||||||
|
LOG(Info, "draggingSession endedAtPoint");
|
||||||
|
MacImpl::DraggingPosition = GetMousePosition(Window, screenPoint);
|
||||||
|
#if USE_EDITOR
|
||||||
|
// Stop background worker once the drag ended
|
||||||
|
if (MacImpl::MacDragSession && MacImpl::MacDragSession == session)
|
||||||
|
Platform::AtomicStore(&MacImpl::MacDragExitFlag, 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
DragDropEffect SDLWindow::DoDragDrop(const StringView& data)
|
DragDropEffect SDLWindow::DoDragDrop(const StringView& data)
|
||||||
{
|
{
|
||||||
return DragDropEffect::None;
|
NSWindow* window = (NSWindow*)_handle;
|
||||||
|
ClipboardDataProviderImpl* clipboardDataProvider = [ClipboardDataProviderImpl alloc];
|
||||||
|
clipboardDataProvider->Window = this;
|
||||||
|
|
||||||
|
// Create mouse drag event
|
||||||
|
NSEvent* event = [NSEvent
|
||||||
|
mouseEventWithType:NSEventTypeLeftMouseDragged
|
||||||
|
location:window.mouseLocationOutsideOfEventStream
|
||||||
|
modifierFlags:0
|
||||||
|
timestamp:NSApp.currentEvent.timestamp
|
||||||
|
windowNumber:window.windowNumber
|
||||||
|
context:nil
|
||||||
|
eventNumber:0
|
||||||
|
clickCount:1
|
||||||
|
pressure:1.0];
|
||||||
|
|
||||||
|
// Create drag item
|
||||||
|
NSPasteboardItem* pasteItem = [NSPasteboardItem new];
|
||||||
|
[pasteItem setDataProvider:clipboardDataProvider forTypes:[NSArray arrayWithObjects:NSPasteboardTypeString, nil]];
|
||||||
|
NSDraggingItem* dragItem = [[NSDraggingItem alloc] initWithPasteboardWriter:pasteItem];
|
||||||
|
[dragItem setDraggingFrame:NSMakeRect(event.locationInWindow.x, event.locationInWindow.y, 100, 100) contents:nil];
|
||||||
|
|
||||||
|
// Start dragging session
|
||||||
|
NSDraggingSession* draggingSession = [window.contentView beginDraggingSessionWithItems:[NSArray arrayWithObject:dragItem] event:event source:clipboardDataProvider];
|
||||||
|
DragDropEffect result = DragDropEffect::None;
|
||||||
|
|
||||||
|
#if USE_EDITOR
|
||||||
|
// Create background worker that will keep updating GUI (perform rendering)
|
||||||
|
ASSERT(!MacImpl::MacDragSession);
|
||||||
|
MacImpl::MacDragSession = draggingSession;
|
||||||
|
MacImpl::MacDragExitFlag = 0;
|
||||||
|
MacImpl::DraggingData = data;
|
||||||
|
MacImpl::DraggingActive = true;
|
||||||
|
while (Platform::AtomicRead(&MacImpl::MacDragExitFlag) == 0)
|
||||||
|
{
|
||||||
|
// The internal event loop will block here during the drag operation,
|
||||||
|
// events are processed in the event filter callback instead.
|
||||||
|
SDLPlatform::Tick();
|
||||||
|
Platform::Sleep(1);
|
||||||
|
}
|
||||||
|
MacImpl::DraggingActive = false;
|
||||||
|
MacImpl::DraggingData.Clear();
|
||||||
|
MacImpl::MacDragSession = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DragDropEffect SDLWindow::DoDragDrop(const StringView& data, const Float2& offset, Window* dragSourceWindow)
|
DragDropEffect SDLWindow::DoDragDrop(const StringView& data, const Float2& offset, Window* dragSourceWindow)
|
||||||
|
|||||||
@@ -1,207 +0,0 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
||||||
|
|
||||||
#if PLATFORM_SDL && PLATFORM_WEB
|
|
||||||
|
|
||||||
#include "SDLWindow.h"
|
|
||||||
#include "Engine/Platform/MessageBox.h"
|
|
||||||
#include "Engine/Core/Log.h"
|
|
||||||
#include <SDL3/SDL_messagebox.h>
|
|
||||||
#include <SDL3/SDL_error.h>
|
|
||||||
|
|
||||||
bool SDLPlatform::InitInternal()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SDLPlatform::UsesWindows()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SDLPlatform::UsesWayland()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SDLPlatform::UsesX11()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SDLPlatform::PreHandleEvents()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void SDLPlatform::PostHandleEvents()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SDLWindow::HandleEventInternal(SDL_Event& event)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SDLPlatform::SetHighDpiAwarenessEnabled(bool enable)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
DragDropEffect SDLWindow::DoDragDrop(const StringView& data)
|
|
||||||
{
|
|
||||||
return DragDropEffect::None;
|
|
||||||
}
|
|
||||||
|
|
||||||
DragDropEffect SDLWindow::DoDragDrop(const StringView& data, const Float2& offset, Window* dragSourceWindow)
|
|
||||||
{
|
|
||||||
Show();
|
|
||||||
return DragDropEffect::None;
|
|
||||||
}
|
|
||||||
|
|
||||||
DialogResult MessageBox::Show(Window* parent, const StringView& text, const StringView& caption, MessageBoxButtons buttons, MessageBoxIcon icon)
|
|
||||||
{
|
|
||||||
StringAnsi textAnsi(text);
|
|
||||||
StringAnsi captionAnsi(caption);
|
|
||||||
|
|
||||||
SDL_MessageBoxData data;
|
|
||||||
SDL_MessageBoxButtonData dataButtons[3];
|
|
||||||
data.window = nullptr;
|
|
||||||
data.title = captionAnsi.GetText();
|
|
||||||
data.message = textAnsi.GetText();
|
|
||||||
data.colorScheme = nullptr;
|
|
||||||
|
|
||||||
switch (icon)
|
|
||||||
{
|
|
||||||
case MessageBoxIcon::Error:
|
|
||||||
case MessageBoxIcon::Hand:
|
|
||||||
case MessageBoxIcon::Stop:
|
|
||||||
data.flags |= SDL_MESSAGEBOX_ERROR;
|
|
||||||
break;
|
|
||||||
case MessageBoxIcon::Asterisk:
|
|
||||||
case MessageBoxIcon::Information:
|
|
||||||
case MessageBoxIcon::Question:
|
|
||||||
data.flags |= SDL_MESSAGEBOX_INFORMATION;
|
|
||||||
break;
|
|
||||||
case MessageBoxIcon::Exclamation:
|
|
||||||
case MessageBoxIcon::Warning:
|
|
||||||
data.flags |= SDL_MESSAGEBOX_WARNING;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (buttons)
|
|
||||||
{
|
|
||||||
case MessageBoxButtons::AbortRetryIgnore:
|
|
||||||
dataButtons[0] =
|
|
||||||
{
|
|
||||||
SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT,
|
|
||||||
(int)DialogResult::Abort,
|
|
||||||
"Abort"
|
|
||||||
};
|
|
||||||
dataButtons[1] =
|
|
||||||
{
|
|
||||||
SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT,
|
|
||||||
(int)DialogResult::Retry,
|
|
||||||
"Retry"
|
|
||||||
};
|
|
||||||
dataButtons[2] =
|
|
||||||
{
|
|
||||||
0,
|
|
||||||
(int)DialogResult::Ignore,
|
|
||||||
"Ignore"
|
|
||||||
};
|
|
||||||
data.numbuttons = 3;
|
|
||||||
break;
|
|
||||||
case MessageBoxButtons::OK:
|
|
||||||
dataButtons[0] =
|
|
||||||
{
|
|
||||||
SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT | SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT,
|
|
||||||
(int)DialogResult::OK,
|
|
||||||
"OK"
|
|
||||||
};
|
|
||||||
data.numbuttons = 1;
|
|
||||||
break;
|
|
||||||
case MessageBoxButtons::OKCancel:
|
|
||||||
dataButtons[0] =
|
|
||||||
{
|
|
||||||
SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT,
|
|
||||||
(int)DialogResult::OK,
|
|
||||||
"OK"
|
|
||||||
};
|
|
||||||
dataButtons[1] =
|
|
||||||
{
|
|
||||||
SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT,
|
|
||||||
(int)DialogResult::Cancel,
|
|
||||||
"Cancel"
|
|
||||||
};
|
|
||||||
data.numbuttons = 2;
|
|
||||||
break;
|
|
||||||
case MessageBoxButtons::RetryCancel:
|
|
||||||
dataButtons[0] =
|
|
||||||
{
|
|
||||||
SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT,
|
|
||||||
(int)DialogResult::Retry,
|
|
||||||
"Retry"
|
|
||||||
};
|
|
||||||
dataButtons[1] =
|
|
||||||
{
|
|
||||||
SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT,
|
|
||||||
(int)DialogResult::Cancel,
|
|
||||||
"Cancel"
|
|
||||||
};
|
|
||||||
data.numbuttons = 2;
|
|
||||||
break;
|
|
||||||
case MessageBoxButtons::YesNo:
|
|
||||||
dataButtons[0] =
|
|
||||||
{
|
|
||||||
SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT,
|
|
||||||
(int)DialogResult::Yes,
|
|
||||||
"Yes"
|
|
||||||
};
|
|
||||||
dataButtons[1] =
|
|
||||||
{
|
|
||||||
SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT,
|
|
||||||
(int)DialogResult::No,
|
|
||||||
"No"
|
|
||||||
};
|
|
||||||
data.numbuttons = 2;
|
|
||||||
break;
|
|
||||||
case MessageBoxButtons::YesNoCancel:
|
|
||||||
{
|
|
||||||
dataButtons[0] =
|
|
||||||
{
|
|
||||||
SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT,
|
|
||||||
(int)DialogResult::Yes,
|
|
||||||
"Yes"
|
|
||||||
};
|
|
||||||
dataButtons[1] =
|
|
||||||
{
|
|
||||||
0,
|
|
||||||
(int)DialogResult::No,
|
|
||||||
"No"
|
|
||||||
};
|
|
||||||
dataButtons[2] =
|
|
||||||
{
|
|
||||||
SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT,
|
|
||||||
(int)DialogResult::Cancel,
|
|
||||||
"Cancel"
|
|
||||||
};
|
|
||||||
data.numbuttons = 3;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
data.buttons = dataButtons;
|
|
||||||
|
|
||||||
int result = -1;
|
|
||||||
if (!SDL_ShowMessageBox(&data, &result))
|
|
||||||
{
|
|
||||||
LOG(Error, "Failed to show SDL message box: {0}", String(SDL_GetError()));
|
|
||||||
return DialogResult::Abort;
|
|
||||||
}
|
|
||||||
if (result < 0)
|
|
||||||
return DialogResult::None;
|
|
||||||
return (DialogResult)result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
namespace SDLImpl
|
namespace SDLImpl
|
||||||
{
|
{
|
||||||
int32 SystemDpi = 96;
|
int32 SystemDpi = 96;
|
||||||
#if PLATFORM_LINUX || PLATFORM_WEB
|
#if PLATFORM_LINUX
|
||||||
String UserLocale("en");
|
String UserLocale("en");
|
||||||
#endif
|
#endif
|
||||||
bool WindowDecorationsSupported = true;
|
bool WindowDecorationsSupported = true;
|
||||||
@@ -109,7 +109,7 @@ bool SDLPlatform::Init()
|
|||||||
if (!SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
|
if (!SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
|
||||||
Platform::Fatal(String::Format(TEXT("Failed to initialize SDL: {0}."), String(SDL_GetError())));
|
Platform::Fatal(String::Format(TEXT("Failed to initialize SDL: {0}."), String(SDL_GetError())));
|
||||||
|
|
||||||
#if PLATFORM_LINUX || PLATFORM_WEB
|
#if PLATFORM_LINUX
|
||||||
int localesCount = 0;
|
int localesCount = 0;
|
||||||
auto locales = SDL_GetPreferredLocales(&localesCount);
|
auto locales = SDL_GetPreferredLocales(&localesCount);
|
||||||
for (int i = 0; i < localesCount; i++)
|
for (int i = 0; i < localesCount; i++)
|
||||||
@@ -241,7 +241,7 @@ int32 SDLPlatform::GetDpi()
|
|||||||
return SDLImpl::SystemDpi;
|
return SDLImpl::SystemDpi;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PLATFORM_LINUX || PLATFORM_WEB
|
#if PLATFORM_LINUX
|
||||||
String SDLPlatform::GetUserLocaleName()
|
String SDLPlatform::GetUserLocaleName()
|
||||||
{
|
{
|
||||||
return SDLImpl::UserLocale;
|
return SDLImpl::UserLocale;
|
||||||
@@ -435,10 +435,8 @@ int32 SDLPlatform::CreateProcess(CreateProcessSettings& settings)
|
|||||||
SDL_SetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ARGS_POINTER, cmd.Get());
|
SDL_SetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ARGS_POINTER, cmd.Get());
|
||||||
SDL_SetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ENVIRONMENT_POINTER, env);
|
SDL_SetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ENVIRONMENT_POINTER, env);
|
||||||
SDL_SetBooleanProperty(props, SDL_PROP_PROCESS_CREATE_BACKGROUND_BOOLEAN, background);
|
SDL_SetBooleanProperty(props, SDL_PROP_PROCESS_CREATE_BACKGROUND_BOOLEAN, background);
|
||||||
#if !PLATFORM_WEB
|
|
||||||
if (workingDirectory.HasChars())
|
if (workingDirectory.HasChars())
|
||||||
SDL_SetStringProperty(props, SDL_PROP_PROCESS_CREATE_WORKING_DIRECTORY_STRING, workingDirectory.Get());
|
SDL_SetStringProperty(props, SDL_PROP_PROCESS_CREATE_WORKING_DIRECTORY_STRING, workingDirectory.Get());
|
||||||
#endif
|
|
||||||
if (captureStdOut)
|
if (captureStdOut)
|
||||||
{
|
{
|
||||||
SDL_SetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER, SDL_PROCESS_STDIO_APP);
|
SDL_SetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER, SDL_PROCESS_STDIO_APP);
|
||||||
|
|||||||
@@ -7,25 +7,29 @@
|
|||||||
#include "Engine/Platform/Base/Enums.h"
|
#include "Engine/Platform/Base/Enums.h"
|
||||||
#if PLATFORM_WINDOWS
|
#if PLATFORM_WINDOWS
|
||||||
#include "Engine/Platform/Windows/WindowsPlatform.h"
|
#include "Engine/Platform/Windows/WindowsPlatform.h"
|
||||||
typedef WindowsPlatform SDLPlatformBase;
|
|
||||||
typedef struct tagMSG MSG;
|
typedef struct tagMSG MSG;
|
||||||
#elif PLATFORM_LINUX
|
#elif PLATFORM_LINUX
|
||||||
#include "Engine/Platform/Linux/LinuxPlatform.h"
|
#include "Engine/Platform/Linux/LinuxPlatform.h"
|
||||||
typedef LinuxPlatform SDLPlatformBase;
|
|
||||||
union _XEvent;
|
union _XEvent;
|
||||||
#elif PLATFORM_MAC
|
#elif PLATFORM_MAC
|
||||||
#include "Engine/Platform/Mac/MacPlatform.h"
|
#include "Engine/Platform/Mac/MacPlatform.h"
|
||||||
typedef MacPlatform SDLPlatformBase;
|
|
||||||
#elif PLATFORM_WEB
|
|
||||||
#include "Engine/Platform/Web/WebPlatform.h"
|
|
||||||
typedef WebPlatform SDLPlatformBase;
|
|
||||||
#else
|
#else
|
||||||
static_assert(false, "Unsupported SDL platform.");
|
static_assert(false, "Unsupported Platform");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class SDLWindow;
|
class SDLWindow;
|
||||||
union SDL_Event;
|
union SDL_Event;
|
||||||
|
|
||||||
|
#if PLATFORM_WINDOWS
|
||||||
|
typedef WindowsPlatform SDLPlatformBase;
|
||||||
|
#elif PLATFORM_LINUX
|
||||||
|
typedef LinuxPlatform SDLPlatformBase;
|
||||||
|
#elif PLATFORM_MAC
|
||||||
|
typedef MacPlatform SDLPlatformBase;
|
||||||
|
#else
|
||||||
|
static_assert(false, "Unsupported SDL platform.");
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The SDL platform implementation and application management utilities.
|
/// The SDL platform implementation and application management utilities.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -80,7 +84,7 @@ public:
|
|||||||
static BatteryInfo GetBatteryInfo();
|
static BatteryInfo GetBatteryInfo();
|
||||||
#endif
|
#endif
|
||||||
static int32 GetDpi();
|
static int32 GetDpi();
|
||||||
#if PLATFORM_LINUX || PLATFORM_WEB
|
#if PLATFORM_LINUX
|
||||||
static String GetUserLocaleName();
|
static String GetUserLocaleName();
|
||||||
#endif
|
#endif
|
||||||
static bool CanOpenUrl(const StringView& url);
|
static bool CanOpenUrl(const StringView& url);
|
||||||
|
|||||||
@@ -38,7 +38,6 @@
|
|||||||
#include "Engine/Platform/Linux/IncludeX11.h"
|
#include "Engine/Platform/Linux/IncludeX11.h"
|
||||||
#elif PLATFORM_MAC
|
#elif PLATFORM_MAC
|
||||||
#include <Cocoa/Cocoa.h>
|
#include <Cocoa/Cocoa.h>
|
||||||
#elif PLATFORM_WEB
|
|
||||||
#else
|
#else
|
||||||
static_assert(false, "Unsupported Platform");
|
static_assert(false, "Unsupported Platform");
|
||||||
#endif
|
#endif
|
||||||
@@ -78,8 +77,6 @@ void* GetNativeWindowPointer(SDL_Window* window)
|
|||||||
windowPtr = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_ANDROID_WINDOW_POINTER, nullptr);
|
windowPtr = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_ANDROID_WINDOW_POINTER, nullptr);
|
||||||
#elif PLATFORM_IOS
|
#elif PLATFORM_IOS
|
||||||
windowPtr = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, nullptr);
|
windowPtr = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, nullptr);
|
||||||
#elif PLATFORM_WEB
|
|
||||||
windowPtr = (void*)1; // Mock value (TODO: consider SDL_PROP_WINDOW_EMSCRIPTEN_CANVAS_ID_STRING)
|
|
||||||
#else
|
#else
|
||||||
static_assert(false, "unsupported platform");
|
static_assert(false, "unsupported platform");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
#include "Platforms/Switch/Engine/Platform/SwitchThread.h"
|
#include "Platforms/Switch/Engine/Platform/SwitchThread.h"
|
||||||
#elif PLATFORM_MAC || PLATFORM_IOS
|
#elif PLATFORM_MAC || PLATFORM_IOS
|
||||||
#include "Apple/AppleThread.h"
|
#include "Apple/AppleThread.h"
|
||||||
#elif PLATFORM_WEB
|
|
||||||
#include "Web/WebThread.h"
|
|
||||||
#else
|
#else
|
||||||
#error Missing Thread implementation!
|
#error Missing Thread implementation!
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -305,29 +305,6 @@ typedef UnixNetwork Network;
|
|||||||
class UserBase;
|
class UserBase;
|
||||||
typedef UserBase User;
|
typedef UserBase User;
|
||||||
|
|
||||||
#elif PLATFORM_WEB
|
|
||||||
|
|
||||||
class UnixCriticalSection;
|
|
||||||
typedef UnixCriticalSection CriticalSection;
|
|
||||||
class UnixReadWriteLock;
|
|
||||||
typedef UnixReadWriteLock ReadWriteLock;
|
|
||||||
class UnixConditionVariable;
|
|
||||||
typedef UnixConditionVariable ConditionVariable;
|
|
||||||
class WebFileSystem;
|
|
||||||
typedef WebFileSystem FileSystem;
|
|
||||||
class FileSystemWatcherBase;
|
|
||||||
typedef FileSystemWatcherBase FileSystemWatcher;
|
|
||||||
class UnixFile;
|
|
||||||
typedef UnixFile File;
|
|
||||||
class WebThread;
|
|
||||||
typedef WebThread Thread;
|
|
||||||
class ClipboardBase;
|
|
||||||
typedef ClipboardBase Clipboard;
|
|
||||||
class UnixNetwork;
|
|
||||||
typedef UnixNetwork Network;
|
|
||||||
class UserBase;
|
|
||||||
typedef UserBase User;
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#error Missing Types implementation!
|
#error Missing Types implementation!
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
#if PLATFORM_UNIX && !PLATFORM_WEB
|
#if PLATFORM_UNIX
|
||||||
|
|
||||||
#include "UnixThread.h"
|
#include "UnixThread.h"
|
||||||
#include "Engine/Core/Log.h"
|
#include "Engine/Core/Log.h"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#if PLATFORM_UNIX && !PLATFORM_WEB
|
#if PLATFORM_UNIX
|
||||||
|
|
||||||
#include "Engine/Platform/Base/ThreadBase.h"
|
#include "Engine/Platform/Base/ThreadBase.h"
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if PLATFORM_WEB
|
|
||||||
|
|
||||||
#include "../Unix/UnixDefines.h"
|
|
||||||
|
|
||||||
// Platform description
|
|
||||||
#define PLATFORM_TYPE PlatformType::Web
|
|
||||||
#define PLATFORM_64BITS 0
|
|
||||||
#define PLATFORM_ARCH ArchitectureType::x86
|
|
||||||
#define PLATFORM_CACHE_LINE_SIZE 64
|
|
||||||
#define PLATFORM_DEBUG_BREAK
|
|
||||||
#define PLATFORM_OUT_OF_MEMORY_BUFFER_SIZE 0
|
|
||||||
|
|
||||||
// Configure graphics
|
|
||||||
#define GPU_ALLOW_TESSELLATION_SHADERS 0
|
|
||||||
#define GPU_ALLOW_GEOMETRY_SHADERS 0
|
|
||||||
#define GPU_ALLOW_PROFILE_EVENTS 0
|
|
||||||
|
|
||||||
// Threading is optional
|
|
||||||
#ifdef __EMSCRIPTEN_PTHREADS__
|
|
||||||
#define PLATFORM_THREADS_LIMIT 4
|
|
||||||
#else
|
|
||||||
#define PLATFORM_THREADS_LIMIT 1
|
|
||||||
#define GPU_ENABLE_ASYNC_RESOURCES_CREATION 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if PLATFORM_WEB
|
|
||||||
|
|
||||||
#include "Engine/Platform/Unix/UnixFileSystem.h"
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Web platform implementation of filesystem service.
|
|
||||||
/// </summary>
|
|
||||||
class FLAXENGINE_API WebFileSystem : public UnixFileSystem
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// [UnixFileSystem]
|
|
||||||
static void GetSpecialFolderPath(const SpecialFolder type, String& result);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,295 +0,0 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
||||||
|
|
||||||
#if PLATFORM_WEB
|
|
||||||
|
|
||||||
#include "WebPlatform.h"
|
|
||||||
#include "WebFileSystem.h"
|
|
||||||
#include "Engine/Core/Log.h"
|
|
||||||
#include "Engine/Core/Types/String.h"
|
|
||||||
#include "Engine/Core/Types/Version.h"
|
|
||||||
#include "Engine/Core/Types/Guid.h"
|
|
||||||
#include "Engine/Core/Collections/Dictionary.h"
|
|
||||||
#include "Engine/Platform/CPUInfo.h"
|
|
||||||
#include "Engine/Platform/MemoryStats.h"
|
|
||||||
#if !BUILD_RELEASE
|
|
||||||
#include "Engine/Core/Types/StringView.h"
|
|
||||||
#include "Engine/Utilities/StringConverter.h"
|
|
||||||
#endif
|
|
||||||
#include <chrono>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <emscripten/emscripten.h>
|
|
||||||
#include <emscripten/threading.h>
|
|
||||||
#include <emscripten/version.h>
|
|
||||||
#include <emscripten/heap.h>
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
CPUInfo Cpu;
|
|
||||||
};
|
|
||||||
|
|
||||||
void WebFileSystem::GetSpecialFolderPath(const SpecialFolder type, String& result)
|
|
||||||
{
|
|
||||||
result = TEXT("/");
|
|
||||||
}
|
|
||||||
|
|
||||||
String WebPlatform::GetSystemName()
|
|
||||||
{
|
|
||||||
return TEXT("Browser");
|
|
||||||
}
|
|
||||||
|
|
||||||
Version WebPlatform::GetSystemVersion()
|
|
||||||
{
|
|
||||||
return Version(1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
CPUInfo WebPlatform::GetCPUInfo()
|
|
||||||
{
|
|
||||||
return Cpu;
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryStats WebPlatform::GetMemoryStats()
|
|
||||||
{
|
|
||||||
// Mock memory stats
|
|
||||||
MemoryStats result;
|
|
||||||
result.TotalPhysicalMemory = emscripten_get_heap_max();
|
|
||||||
result.UsedPhysicalMemory = emscripten_get_heap_size();
|
|
||||||
result.TotalVirtualMemory = 2ull * 1024 * 1024 * 1024; // Max 2GB
|
|
||||||
result.UsedVirtualMemory = result.UsedPhysicalMemory;
|
|
||||||
result.ProgramSizeMemory = 0;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
ProcessMemoryStats WebPlatform::GetProcessMemoryStats()
|
|
||||||
{
|
|
||||||
// Mock memory stats
|
|
||||||
ProcessMemoryStats result;
|
|
||||||
result.UsedPhysicalMemory = 1 * 1024 * 1024;
|
|
||||||
result.UsedVirtualMemory = result.UsedPhysicalMemory;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebPlatform::SetThreadPriority(ThreadPriority priority)
|
|
||||||
{
|
|
||||||
// Not supported
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebPlatform::SetThreadAffinityMask(uint64 affinityMask)
|
|
||||||
{
|
|
||||||
// Not supported
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebPlatform::Sleep(int32 milliseconds)
|
|
||||||
{
|
|
||||||
//emscripten_sleep(milliseconds);
|
|
||||||
emscripten_thread_sleep(milliseconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebPlatform::Yield()
|
|
||||||
{
|
|
||||||
Sleep(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
double WebPlatform::GetTimeSeconds()
|
|
||||||
{
|
|
||||||
double time = emscripten_get_now();
|
|
||||||
return time * 0.001;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64 WebPlatform::GetTimeCycles()
|
|
||||||
{
|
|
||||||
return (uint64)(emscripten_get_now() * 1000.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebPlatform::GetSystemTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond)
|
|
||||||
{
|
|
||||||
// Get local time
|
|
||||||
using namespace std::chrono;
|
|
||||||
system_clock::time_point now = system_clock::now();
|
|
||||||
time_t tt = system_clock::to_time_t(now);
|
|
||||||
tm time = *localtime(&tt);
|
|
||||||
|
|
||||||
// Extract time
|
|
||||||
year = time.tm_year + 1900;
|
|
||||||
month = time.tm_mon + 1;
|
|
||||||
dayOfWeek = time.tm_wday;
|
|
||||||
day = time.tm_mday;
|
|
||||||
hour = time.tm_hour;
|
|
||||||
minute = time.tm_min;
|
|
||||||
second = time.tm_sec;
|
|
||||||
millisecond = (int64)emscripten_get_now() % 1000; // Fake it based on other timer
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebPlatform::GetUTCTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond)
|
|
||||||
{
|
|
||||||
// Get UTC time
|
|
||||||
using namespace std::chrono;
|
|
||||||
system_clock::time_point now = system_clock::now();
|
|
||||||
time_t tt = system_clock::to_time_t(now);
|
|
||||||
tm time = *gmtime(&tt);
|
|
||||||
|
|
||||||
// Extract time
|
|
||||||
year = time.tm_year + 1900;
|
|
||||||
month = time.tm_mon + 1;
|
|
||||||
dayOfWeek = time.tm_wday;
|
|
||||||
day = time.tm_mday;
|
|
||||||
hour = time.tm_hour;
|
|
||||||
minute = time.tm_min;
|
|
||||||
second = time.tm_sec;
|
|
||||||
millisecond = (int64)emscripten_get_now() % 1000; // Fake it based on other timer
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !BUILD_RELEASE
|
|
||||||
|
|
||||||
void WebPlatform::Log(const StringView& msg)
|
|
||||||
{
|
|
||||||
const StringAsANSI<512> msgAnsi(*msg, msg.Length());
|
|
||||||
|
|
||||||
// Fix % characters that should not be formatted
|
|
||||||
auto buffer = (char*)msgAnsi.Get();
|
|
||||||
for (int32 i = 0; buffer[i]; i++)
|
|
||||||
{
|
|
||||||
if (buffer[i] == '%')
|
|
||||||
buffer[i] = 'p';
|
|
||||||
}
|
|
||||||
|
|
||||||
emscripten_log(EM_LOG_CONSOLE, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WebPlatform::IsDebuggerPresent()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
String WebPlatform::GetComputerName()
|
|
||||||
{
|
|
||||||
return TEXT("Web");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WebPlatform::GetHasFocus()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
String WebPlatform::GetMainDirectory()
|
|
||||||
{
|
|
||||||
return TEXT("/");
|
|
||||||
}
|
|
||||||
|
|
||||||
String WebPlatform::GetExecutableFilePath()
|
|
||||||
{
|
|
||||||
return TEXT("/index.html");
|
|
||||||
}
|
|
||||||
|
|
||||||
Guid WebPlatform::GetUniqueDeviceId()
|
|
||||||
{
|
|
||||||
return Guid(1, 2, 3, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
String WebPlatform::GetWorkingDirectory()
|
|
||||||
{
|
|
||||||
return GetMainDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WebPlatform::SetWorkingDirectory(const String& path)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WebPlatform::Init()
|
|
||||||
{
|
|
||||||
if (PlatformBase::Init())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Set info about the CPU
|
|
||||||
Platform::MemoryClear(&Cpu, sizeof(Cpu));
|
|
||||||
Cpu.ProcessorPackageCount = 1;
|
|
||||||
Cpu.ProcessorCoreCount = Math::Min(emscripten_num_logical_cores(), PLATFORM_THREADS_LIMIT);
|
|
||||||
Cpu.LogicalProcessorCount = Cpu.ProcessorCoreCount;
|
|
||||||
Cpu.ClockSpeed = GetClockFrequency();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebPlatform::LogInfo()
|
|
||||||
{
|
|
||||||
PlatformBase::LogInfo();
|
|
||||||
|
|
||||||
#ifdef __EMSCRIPTEN_major__
|
|
||||||
LOG(Info, "Emscripten {}.{}.{}", __EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__);
|
|
||||||
#elif defined(__EMSCRIPTEN_MAJOR__)
|
|
||||||
LOG(Info, "Emscripten {}.{}.{}", __EMSCRIPTEN_MAJOR__, __EMSCRIPTEN_MINOR__, __EMSCRIPTEN_TINY__);
|
|
||||||
#else
|
|
||||||
LOG(Info, "Emscripten");
|
|
||||||
#endif
|
|
||||||
#ifdef __EMSCRIPTEN_PTHREADS__
|
|
||||||
LOG(Info, "Threading: pthreads");
|
|
||||||
#else
|
|
||||||
LOG(Info, "Threading: disabled");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebPlatform::Tick()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebPlatform::Exit()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
extern char** environ;
|
|
||||||
|
|
||||||
void WebPlatform::GetEnvironmentVariables(Dictionary<String, String, HeapAllocation>& result)
|
|
||||||
{
|
|
||||||
char** s = environ;
|
|
||||||
for (; *s; s++)
|
|
||||||
{
|
|
||||||
char* var = *s;
|
|
||||||
int32 split = -1;
|
|
||||||
for (int32 i = 0; var[i]; i++)
|
|
||||||
{
|
|
||||||
if (var[i] == '=')
|
|
||||||
{
|
|
||||||
split = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (split == -1)
|
|
||||||
result[String(var)] = String::Empty;
|
|
||||||
else
|
|
||||||
result[String(var, split)] = String(var + split + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WebPlatform::GetEnvironmentVariable(const String& name, String& value)
|
|
||||||
{
|
|
||||||
char* env = getenv(StringAsANSI<>(*name).Get());
|
|
||||||
if (env)
|
|
||||||
{
|
|
||||||
value = String(env);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WebPlatform::SetEnvironmentVariable(const String& name, const String& value)
|
|
||||||
{
|
|
||||||
return setenv(StringAsANSI<>(*name).Get(), StringAsANSI<>(*value).Get(), true) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* WebPlatform::LoadLibrary(const Char* filename)
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebPlatform::FreeLibrary(void* handle)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void* WebPlatform::GetProcAddress(void* handle, const char* symbol)
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if PLATFORM_WEB
|
|
||||||
|
|
||||||
#include "../Unix/UnixPlatform.h"
|
|
||||||
#ifdef __EMSCRIPTEN_PTHREADS__
|
|
||||||
#include <pthread.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Web platform implementation and application management utilities.
|
|
||||||
/// </summary>
|
|
||||||
class FLAXENGINE_API WebPlatform : public UnixPlatform
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// [UnixPlatform]
|
|
||||||
FORCE_INLINE static void MemoryBarrier()
|
|
||||||
{
|
|
||||||
#ifdef __EMSCRIPTEN_PTHREADS__
|
|
||||||
// Fake a fence with an arbitrary atomic operation (from emscripten_atomic_fence to avoid including it for less header bloat)
|
|
||||||
uint8 temp = 0;
|
|
||||||
__c11_atomic_fetch_or((_Atomic uint8*)&temp, 0, __ATOMIC_SEQ_CST);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
FORCE_INLINE static void MemoryPrefetch(void const* ptr)
|
|
||||||
{
|
|
||||||
__builtin_prefetch(static_cast<char const*>(ptr));
|
|
||||||
}
|
|
||||||
FORCE_INLINE static int64 InterlockedExchange(int64 volatile* dst, int64 exchange)
|
|
||||||
{
|
|
||||||
return __sync_lock_test_and_set(dst, exchange);
|
|
||||||
}
|
|
||||||
FORCE_INLINE static int32 InterlockedCompareExchange(int32 volatile* dst, int32 exchange, int32 comperand)
|
|
||||||
{
|
|
||||||
return __sync_val_compare_and_swap(dst, comperand, exchange);
|
|
||||||
}
|
|
||||||
FORCE_INLINE static int64 InterlockedCompareExchange(int64 volatile* dst, int64 exchange, int64 comperand)
|
|
||||||
{
|
|
||||||
return __sync_val_compare_and_swap(dst, comperand, exchange);
|
|
||||||
}
|
|
||||||
FORCE_INLINE static int64 InterlockedIncrement(int64 volatile* dst)
|
|
||||||
{
|
|
||||||
return __sync_add_and_fetch(dst, 1);
|
|
||||||
}
|
|
||||||
FORCE_INLINE static int64 InterlockedDecrement(int64 volatile* dst)
|
|
||||||
{
|
|
||||||
return __sync_sub_and_fetch(dst, 1);
|
|
||||||
}
|
|
||||||
FORCE_INLINE static int64 InterlockedAdd(int64 volatile* dst, int64 value)
|
|
||||||
{
|
|
||||||
return __sync_fetch_and_add(dst, value);
|
|
||||||
}
|
|
||||||
FORCE_INLINE static int32 AtomicRead(int32 const volatile* dst)
|
|
||||||
{
|
|
||||||
int32 result;
|
|
||||||
__atomic_load(dst, &result, __ATOMIC_SEQ_CST);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
FORCE_INLINE static int64 AtomicRead(int64 const volatile* dst)
|
|
||||||
{
|
|
||||||
int64 result;
|
|
||||||
__atomic_load(dst, &result, __ATOMIC_SEQ_CST);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
FORCE_INLINE static void AtomicStore(int32 volatile* dst, int32 value)
|
|
||||||
{
|
|
||||||
__atomic_store(dst, &value, __ATOMIC_SEQ_CST);
|
|
||||||
}
|
|
||||||
FORCE_INLINE static void AtomicStore(int64 volatile* dst, int64 value)
|
|
||||||
{
|
|
||||||
__atomic_store(dst, &value, __ATOMIC_SEQ_CST);
|
|
||||||
}
|
|
||||||
FORCE_INLINE static uint64 GetCurrentThreadID()
|
|
||||||
{
|
|
||||||
#ifdef __EMSCRIPTEN_PTHREADS__
|
|
||||||
return (uint64)pthread_self();
|
|
||||||
#else
|
|
||||||
return 1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
static String GetSystemName();
|
|
||||||
static Version GetSystemVersion();
|
|
||||||
static CPUInfo GetCPUInfo();
|
|
||||||
static MemoryStats GetMemoryStats();
|
|
||||||
static ProcessMemoryStats GetProcessMemoryStats();
|
|
||||||
static void SetThreadPriority(ThreadPriority priority);
|
|
||||||
static void SetThreadAffinityMask(uint64 affinityMask);
|
|
||||||
static void Sleep(int32 milliseconds);
|
|
||||||
static void Yield();
|
|
||||||
static double GetTimeSeconds();
|
|
||||||
static uint64 GetTimeCycles();
|
|
||||||
static void GetSystemTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond);
|
|
||||||
static void GetUTCTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond);
|
|
||||||
#if !BUILD_RELEASE
|
|
||||||
static void Log(const StringView& msg);
|
|
||||||
static bool IsDebuggerPresent();
|
|
||||||
#endif
|
|
||||||
static String GetComputerName();
|
|
||||||
static bool GetHasFocus();
|
|
||||||
static String GetMainDirectory();
|
|
||||||
static String GetExecutableFilePath();
|
|
||||||
static Guid GetUniqueDeviceId();
|
|
||||||
static String GetWorkingDirectory();
|
|
||||||
static bool SetWorkingDirectory(const String& path);
|
|
||||||
static bool Init();
|
|
||||||
static void LogInfo();
|
|
||||||
static void Tick();
|
|
||||||
static void Exit();
|
|
||||||
static void GetEnvironmentVariables(Dictionary<String, String, HeapAllocation>& result);
|
|
||||||
static bool GetEnvironmentVariable(const String& name, String& value);
|
|
||||||
static bool SetEnvironmentVariable(const String& name, const String& value);
|
|
||||||
static void* LoadLibrary(const Char* filename);
|
|
||||||
static void FreeLibrary(void* handle);
|
|
||||||
static void* GetProcAddress(void* handle, const char* symbol);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if PLATFORM_WEB || USE_EDITOR
|
|
||||||
|
|
||||||
#include "Engine/Core/Config/PlatformSettingsBase.h"
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Web platform settings.
|
|
||||||
/// </summary>
|
|
||||||
API_CLASS(Sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API WebPlatformSettings : public SettingsBase
|
|
||||||
{
|
|
||||||
DECLARE_SCRIPTING_TYPE_MINIMAL(WebPlatformSettings);
|
|
||||||
API_AUTO_SERIALIZATION();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the instance of the settings asset (default value if missing). Object returned by this method is always loaded with valid data to use.
|
|
||||||
/// </summary>
|
|
||||||
static WebPlatformSettings* Get();
|
|
||||||
};
|
|
||||||
|
|
||||||
#if PLATFORM_WEB
|
|
||||||
typedef WebPlatformSettings PlatformSettings;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if PLATFORM_WEB
|
|
||||||
|
|
||||||
#include "../Base/ThreadBase.h"
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Thread object for Web platform.
|
|
||||||
/// </summary>
|
|
||||||
class FLAXENGINE_API WebThread : public ThreadBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="WebThreadThread"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="runnable">The runnable.</param>
|
|
||||||
/// <param name="name">The thread name.</param>
|
|
||||||
/// <param name="priority">The thread priority.</param>
|
|
||||||
WebThread(IRunnable* runnable, const String& name, ThreadPriority priority)
|
|
||||||
: ThreadBase(runnable, name, priority)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// <summary>
|
|
||||||
/// Factory method to create a thread with the specified stack size and thread priority
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="runnable">The runnable object to execute</param>
|
|
||||||
/// <param name="name">Name of the thread</param>
|
|
||||||
/// <param name="priority">Tells the thread whether it needs to adjust its priority or not. Defaults to normal priority</param>
|
|
||||||
/// <param name="stackSize">The size of the stack to create. 0 means use the current thread's stack size</param>
|
|
||||||
/// <returns>Pointer to the new thread or null if cannot create it</returns>
|
|
||||||
static WebThread* Create(IRunnable* runnable, const String& name, ThreadPriority priority = ThreadPriority::Normal, uint32 stackSize = 0)
|
|
||||||
{
|
|
||||||
return New<WebThread>(runnable, name, priority);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
// [ThreadBase]
|
|
||||||
void Join() override
|
|
||||||
{
|
|
||||||
// TOOD: impl this
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// [ThreadBase]
|
|
||||||
void ClearHandleInternal() override
|
|
||||||
{
|
|
||||||
// TOOD: impl this
|
|
||||||
}
|
|
||||||
void SetPriorityInternal(ThreadPriority priority) override
|
|
||||||
{
|
|
||||||
// TOOD: impl this
|
|
||||||
}
|
|
||||||
void KillInternal(bool waitForJoin) override
|
|
||||||
{
|
|
||||||
// TOOD: impl this
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
API_CLASS(Sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API iOSPlatformSettings : public ApplePlatformSettings
|
API_CLASS(Sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API iOSPlatformSettings : public ApplePlatformSettings
|
||||||
{
|
{
|
||||||
DECLARE_SCRIPTING_TYPE_MINIMAL(iOSPlatformSettings);
|
DECLARE_SCRIPTING_TYPE_MINIMAL(ApplePlatformSettings);
|
||||||
API_AUTO_SERIALIZATION();
|
API_AUTO_SERIALIZATION();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ public class Profiler : EngineModule
|
|||||||
/// <returns>True if use profiler, otherwise false.</returns>
|
/// <returns>True if use profiler, otherwise false.</returns>
|
||||||
public static bool Use(BuildOptions options)
|
public static bool Use(BuildOptions options)
|
||||||
{
|
{
|
||||||
if (options.Platform.Target == TargetPlatform.Web)
|
|
||||||
return false;
|
|
||||||
return options.Configuration != TargetConfiguration.Release || options.Target.IsEditor;
|
return options.Configuration != TargetConfiguration.Release || options.Target.IsEditor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -304,7 +304,7 @@ GPUTexture* ScreenSpaceReflectionsPass::Render(RenderContext& renderContext, GPU
|
|||||||
// Also for high surface roughness values it adds more blur to the reflection tail which looks more realistic.
|
// Also for high surface roughness values it adds more blur to the reflection tail which looks more realistic.
|
||||||
|
|
||||||
// Downscale with gaussian blur
|
// Downscale with gaussian blur
|
||||||
auto filterMode = PLATFORM_WEB || PLATFORM_ANDROID || PLATFORM_IOS || PLATFORM_SWITCH ? MultiScaler::FilterMode::GaussianBlur5 : MultiScaler::FilterMode::GaussianBlur9;
|
auto filterMode = PLATFORM_ANDROID || PLATFORM_IOS || PLATFORM_SWITCH ? MultiScaler::FilterMode::GaussianBlur5 : MultiScaler::FilterMode::GaussianBlur9;
|
||||||
for (int32 mipLevel = 1; mipLevel < colorBufferMips; mipLevel++)
|
for (int32 mipLevel = 1; mipLevel < colorBufferMips; mipLevel++)
|
||||||
{
|
{
|
||||||
const int32 mipWidth = Math::Max(colorBufferWidth >> mipLevel, 1);
|
const int32 mipWidth = Math::Max(colorBufferWidth >> mipLevel, 1);
|
||||||
|
|||||||
@@ -784,7 +784,7 @@ void ShadowsPass::SetupLight(ShadowsCustomBuffer& shadows, RenderContext& render
|
|||||||
// Disable cascades blending when baking lightmaps
|
// Disable cascades blending when baking lightmaps
|
||||||
if (IsRunningRadiancePass)
|
if (IsRunningRadiancePass)
|
||||||
atlasLight.BlendCSM = false;
|
atlasLight.BlendCSM = false;
|
||||||
#elif PLATFORM_WEB || PLATFORM_SWITCH || PLATFORM_IOS || PLATFORM_ANDROID
|
#elif PLATFORM_SWITCH || PLATFORM_IOS || PLATFORM_ANDROID
|
||||||
// Disable cascades blending on low-end platforms
|
// Disable cascades blending on low-end platforms
|
||||||
atlasLight.BlendCSM = false;
|
atlasLight.BlendCSM = false;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -573,7 +573,6 @@ bool Scripting::Load()
|
|||||||
auto* flaxEngineModule = (NativeBinaryModule*)GetBinaryModuleFlaxEngine();
|
auto* flaxEngineModule = (NativeBinaryModule*)GetBinaryModuleFlaxEngine();
|
||||||
if (!flaxEngineModule->Assembly->IsLoaded())
|
if (!flaxEngineModule->Assembly->IsLoaded())
|
||||||
{
|
{
|
||||||
#if USE_CSHARP
|
|
||||||
String flaxEnginePath = Globals::BinariesFolder / TEXT("FlaxEngine.CSharp.dll");
|
String flaxEnginePath = Globals::BinariesFolder / TEXT("FlaxEngine.CSharp.dll");
|
||||||
#if USE_MONO_AOT
|
#if USE_MONO_AOT
|
||||||
if (!FileSystem::FileExists(flaxEnginePath))
|
if (!FileSystem::FileExists(flaxEnginePath))
|
||||||
@@ -584,7 +583,6 @@ bool Scripting::Load()
|
|||||||
LOG(Error, "Failed to load FlaxEngine C# assembly.");
|
LOG(Error, "Failed to load FlaxEngine C# assembly.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
flaxEngineModule->CanReload = false;
|
flaxEngineModule->CanReload = false;
|
||||||
flaxEngineModule->Assembly->_canReload = false;
|
flaxEngineModule->Assembly->_canReload = false;
|
||||||
onEngineLoaded(flaxEngineModule->Assembly);
|
onEngineLoaded(flaxEngineModule->Assembly);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "JsonTools.h"
|
#include "JsonTools.h"
|
||||||
#include "ISerializable.h"
|
#include "ISerializable.h"
|
||||||
#include "Engine/Core/Collections/Dictionary.h"
|
#include "Engine/Core/Collections/Dictionary.h"
|
||||||
|
#include "Engine/Core/Types/CommonValue.h"
|
||||||
#include "Engine/Core/Types/DateTime.h"
|
#include "Engine/Core/Types/DateTime.h"
|
||||||
#include "Engine/Profiler/ProfilerCPU.h"
|
#include "Engine/Profiler/ProfilerCPU.h"
|
||||||
#include "Engine/Scripting/ScriptingObjectReference.h"
|
#include "Engine/Scripting/ScriptingObjectReference.h"
|
||||||
@@ -283,3 +284,87 @@ DateTime JsonTools::GetDateTime(const Value& value)
|
|||||||
{
|
{
|
||||||
return DateTime(value.GetInt64());
|
return DateTime(value.GetInt64());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||||
|
#include "Engine/Content/Deprecated.h"
|
||||||
|
CommonValue JsonTools::GetCommonValue(const Value& value)
|
||||||
|
{
|
||||||
|
// [Deprecated on 31.07.2020, expires on 31.07.2022]
|
||||||
|
MARK_CONTENT_DEPRECATED();
|
||||||
|
CommonValue result;
|
||||||
|
const auto typeMember = value.FindMember("Type");
|
||||||
|
const auto valueMember = value.FindMember("Value");
|
||||||
|
if (typeMember != value.MemberEnd() && typeMember->value.IsInt() && valueMember != value.MemberEnd())
|
||||||
|
{
|
||||||
|
const auto& v = valueMember->value;
|
||||||
|
switch ((CommonType)typeMember->value.GetInt())
|
||||||
|
{
|
||||||
|
case CommonType::Bool:
|
||||||
|
result = v.GetBool();
|
||||||
|
break;
|
||||||
|
case CommonType::Integer:
|
||||||
|
result = v.GetInt();
|
||||||
|
break;
|
||||||
|
case CommonType::Float:
|
||||||
|
result = v.GetFloat();
|
||||||
|
break;
|
||||||
|
case CommonType::Vector2:
|
||||||
|
result = GetFloat2(v);
|
||||||
|
break;
|
||||||
|
case CommonType::Vector3:
|
||||||
|
result = GetFloat3(v);
|
||||||
|
break;
|
||||||
|
case CommonType::Vector4:
|
||||||
|
result = GetFloat4(v);
|
||||||
|
break;
|
||||||
|
case CommonType::Color:
|
||||||
|
result = GetColor(v);
|
||||||
|
break;
|
||||||
|
case CommonType::Guid:
|
||||||
|
result = GetGuid(v);
|
||||||
|
break;
|
||||||
|
case CommonType::String:
|
||||||
|
result = v.GetText();
|
||||||
|
break;
|
||||||
|
case CommonType::Box:
|
||||||
|
result = GetBoundingBox(v);
|
||||||
|
break;
|
||||||
|
case CommonType::Rotation:
|
||||||
|
result = GetQuaternion(v);
|
||||||
|
break;
|
||||||
|
case CommonType::Transform:
|
||||||
|
result = GetTransform(v);
|
||||||
|
break;
|
||||||
|
case CommonType::Sphere:
|
||||||
|
result = GetBoundingSphere(v);
|
||||||
|
break;
|
||||||
|
case CommonType::Rectangle:
|
||||||
|
result = GetRectangle(v);
|
||||||
|
break;
|
||||||
|
case CommonType::Ray:
|
||||||
|
result = GetRay(v);
|
||||||
|
break;
|
||||||
|
case CommonType::Pointer:
|
||||||
|
result = (void*)v.GetInt64();
|
||||||
|
break;
|
||||||
|
case CommonType::Matrix:
|
||||||
|
result = GetMatrix(v);
|
||||||
|
break;
|
||||||
|
case CommonType::Blob:
|
||||||
|
{
|
||||||
|
const int32 length = v.GetStringLength();
|
||||||
|
result.SetBlob(length);
|
||||||
|
Encryption::Base64Decode(v.GetString(), length, result.AsBlob.Data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CommonType::Object:
|
||||||
|
result = FindObject(GetGuid(v), ScriptingObject::GetStaticClass());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CRASH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user