Merge branch '1.1' of https://github.com/FlaxEngine/FlaxEngine into orientation

This commit is contained in:
Jean-Baptiste Perrier
2021-02-27 17:02:42 +01:00
32 changed files with 435 additions and 162 deletions

View File

@@ -2,8 +2,10 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Xml;
using FlaxEditor.GUI;
using FlaxEditor.GUI.ContextMenu;
@@ -183,6 +185,11 @@ namespace FlaxEditor.Windows
return true;
}
}
// Enter
else if (key == KeyboardKeys.Return)
{
Open();
}
// Ctrl+C
else if (key == KeyboardKeys.C && Root.GetKey(KeyboardKeys.Control))
{
@@ -193,19 +200,28 @@ namespace FlaxEditor.Windows
return base.OnKeyDown(key);
}
/// <summary>
/// Opens the entry location.
/// </summary>
public void Open()
{
if (!string.IsNullOrEmpty(Desc.LocationFile) && File.Exists(Desc.LocationFile))
{
Editor.Instance.CodeEditing.OpenFile(Desc.LocationFile, Desc.LocationLine);
}
}
/// <summary>
/// Copies the entry information to the system clipboard (as text).
/// </summary>
public void Copy()
{
Clipboard.Text = Info.Replace("\n", Environment.NewLine);
Clipboard.Text = Info.Replace("\r\n", "\n").Replace("\n", Environment.NewLine);
}
public override bool OnMouseDoubleClick(Vector2 location, MouseButton button)
{
// Show the location
Editor.Instance.CodeEditing.OpenFile(Desc.LocationFile, Desc.LocationLine);
Open();
return true;
}
@@ -238,6 +254,7 @@ namespace FlaxEditor.Windows
var menu = new ContextMenu();
menu.AddButton("Copy", Copy);
menu.AddButton("Open", Open).Enabled = !string.IsNullOrEmpty(Desc.LocationFile) && File.Exists(Desc.LocationFile);
menu.Show(this, location);
}
@@ -258,7 +275,8 @@ namespace FlaxEditor.Windows
private readonly VerticalPanel _entriesPanel;
private LogEntry _selected;
private readonly int[] _logCountPerGroup = new int[(int)LogGroup.Max];
private readonly Regex _logRegex = new Regex("at(.*) in (.*):(\\d*)");
private readonly Regex _logRegex = new Regex("at (.*) in (.*):(line (\\d*)|(\\d*))");
private readonly ThreadLocal<StringBuilder> _stringBuilder = new ThreadLocal<StringBuilder>(() => new StringBuilder(), false);
private InterfaceOptions.TimestampsFormats _timestampsFormats;
private readonly object _locker = new object();
@@ -337,7 +355,6 @@ namespace FlaxEditor.Windows
Editor.Options.OptionsChanged += OnEditorOptionsChanged;
Debug.Logger.LogHandler.SendLog += LogHandlerOnSendLog;
Debug.Logger.LogHandler.SendExceptionLog += LogHandlerOnSendExceptionLog;
}
private void OnEditorOptionsChanged(EditorOptions options)
@@ -488,24 +505,33 @@ namespace FlaxEditor.Windows
// Detect code location and remove leading internal stack trace part
var matches = _logRegex.Matches(stackTrace);
bool foundStart = false, noLocation = true;
var fineStackTrace = new StringBuilder(stackTrace.Length);
var fineStackTrace = _stringBuilder.Value;
fineStackTrace.Clear();
fineStackTrace.Capacity = Mathf.Max(fineStackTrace.Capacity, stackTrace.Length);
for (int i = 0; i < matches.Count; i++)
{
var match = matches[i];
if (foundStart)
var matchLocation = match.Groups[1].Value.Trim();
if (matchLocation.StartsWith("FlaxEngine.Debug.", StringComparison.Ordinal))
{
// C# start
foundStart = true;
}
else if (matchLocation.StartsWith("DebugLog::", StringComparison.Ordinal))
{
// C++ start
foundStart = true;
}
else if (foundStart)
{
if (noLocation)
{
desc.LocationFile = match.Groups[2].Value;
int.TryParse(match.Groups[3].Value, out desc.LocationLine);
int.TryParse(match.Groups[5].Value, out desc.LocationLine);
noLocation = false;
}
fineStackTrace.AppendLine(match.Groups[0].Value);
}
else if (match.Groups[1].Value.Trim().StartsWith("FlaxEngine.Debug.Info", StringComparison.Ordinal))
{
foundStart = true;
}
}
desc.Description = fineStackTrace.ToString();
}

View File

@@ -193,7 +193,7 @@ public:
FORCE_INLINE AssetReference& operator=(const Guid& id)
{
OnSet((T*)LoadAsset(id, T::TypeInitializer));
OnSet((T*)::LoadAsset(id, T::TypeInitializer));
return *this;
}

View File

@@ -3,6 +3,7 @@
#include "VisualScript.h"
#include "Engine/Core/Log.h"
#include "Engine/Core/Types/DataContainer.h"
#include "Engine/Content/Content.h"
#include "Engine/Content/Factories/BinaryAssetFactory.h"
#include "Engine/Scripting/MException.h"
#include "Engine/Scripting/Scripting.h"

View File

@@ -2,10 +2,9 @@
#pragma once
#include "Engine/Content/Content.h"
#include "Engine/Core/Collections/Array.h"
#include "Engine/Content/AssetReference.h"
#include "../Asset.h"
#include "Asset.h"
/// <summary>
/// Assets Container allows to load collection of assets and keep references to them.
@@ -27,13 +26,9 @@ public:
if (e.GetID() == id)
return (T*)e.Get();
}
auto asset = Content::LoadAsync<T>(id);
auto asset = (T*)::LoadAsset(id, T::TypeInitializer);
if (asset)
{
Add(asset);
}
return asset;
}

View File

@@ -158,7 +158,7 @@ public:
FORCE_INLINE WeakAssetReference& operator=(const Guid& id)
{
OnSet((T*)LoadAsset(id, T::TypeInitializer));
OnSet((T*)::LoadAsset(id, T::TypeInitializer));
return *this;
}

View File

@@ -1,9 +1,11 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#if COMPILE_WITH_ASSETS_IMPORTER
#include "ImportIES.h"
#include "Engine/Core/Log.h"
#include "Engine/Core/RandomStream.h"
#include "Engine/Core/Math/Packed.h"
#include "IESLoader.h"
#define MAX_LINE 200
@@ -84,7 +86,7 @@ static bool ReadLine(const uint8*& bufferPos, int32& ret)
#define PARSE_FLOAT(x) float x; if (!ReadFloat(bufferPos, x)) { return true; }
#define PARSE_INT(x) int32 x; if (!ReadLine(bufferPos, x)) { return true; }
bool IESLoader::Load(const byte* buffer)
bool ImportIES::Load(const byte* buffer)
{
// Referenced IES file format:
// http://www.ltblight.com/English.lproj/LTBLhelp/pages/iesformat.html
@@ -214,7 +216,7 @@ bool IESLoader::Load(const byte* buffer)
#undef PARSE_FLOAT
#undef PARSE_INT
float IESLoader::ExtractInR16(Array<byte>& output)
float ImportIES::ExtractInR16(Array<byte>& output)
{
const uint32 width = GetWidth();
const uint32 height = GetHeight();
@@ -263,14 +265,14 @@ float IESLoader::ExtractInR16(Array<byte>& output)
return maxValue / integral;
}
float IESLoader::InterpolatePoint(int32 x, int32 y) const
float ImportIES::InterpolatePoint(int32 x, int32 y) const
{
x %= _hAngles.Count();
y %= _vAngles.Count();
return _candalaValues[y + _vAngles.Count() * x];
}
float IESLoader::InterpolateBilinear(float x, float y) const
float ImportIES::InterpolateBilinear(float x, float y) const
{
const int32 xInt = static_cast<int32>(x);
const int32 yInt = static_cast<int32>(y);
@@ -289,7 +291,7 @@ float IESLoader::InterpolateBilinear(float x, float y) const
return Math::Lerp(p0, p1, xFrac);
}
float IESLoader::ComputeFilterPos(float value, const Array<float>& sortedValues)
float ImportIES::ComputeFilterPos(float value, const Array<float>& sortedValues)
{
ASSERT(sortedValues.HasItems());
@@ -336,3 +338,5 @@ float IESLoader::ComputeFilterPos(float value, const Array<float>& sortedValues)
return startPos + fraction;
}
#endif

View File

@@ -2,13 +2,15 @@
#pragma once
#if COMPILE_WITH_ASSETS_IMPORTER
#include "Engine/Core/Types/BaseTypes.h"
#include "Engine/Core/Collections/Array.h"
/// <summary>
/// Utility for loading IES files and extract light emission information.
/// </summary>
class IESLoader
class ImportIES
{
private:
@@ -56,3 +58,5 @@ private:
float InterpolateBilinear(float x, float y) const;
static float ComputeFilterPos(float value, const Array<float>& sortedValues);
};
#endif

View File

@@ -13,7 +13,7 @@
#include "Engine/Graphics/Textures/TextureUtils.h"
#include "Engine/Graphics/PixelFormatExtensions.h"
#include "Engine/Content/Storage/ContentStorageManager.h"
#include "Engine/Content/Utilities/IESLoader.h"
#include "Engine/ContentImporters/ImportIES.h"
#include "Engine/Content/Assets/CubeTexture.h"
#include "Engine/Content/Assets/IESProfile.h"
#include "Engine/Content/Assets/Texture.h"
@@ -527,7 +527,7 @@ CreateAssetResult ImportTexture::ImportIES(class CreateAssetContext& context)
fileData.Add('\0');
// Load IES profile data
IESLoader loader;
::ImportIES loader;
if (loader.Load(fileData.Get()))
{
return CreateAssetResult::Error;

View File

@@ -968,6 +968,17 @@ namespace FlaxEngine
RotationMatrix(ref matrix, out result);
}
/// <summary>
/// Creates a left-handed, look-at quaternion.
/// </summary>
/// <param name="eye">The position of the viewer's eye.</param>
/// <param name="target">The camera look-at target.</param>
/// <returns>The created look-at quaternion.</returns>
public static Quaternion LookAt(Vector3 eye, Vector3 target)
{
return LookAt(eye, target, Vector3.Up);
}
/// <summary>
/// Creates a left-handed, look-at quaternion.
/// </summary>
@@ -993,6 +1004,16 @@ namespace FlaxEngine
LookAt(ref eye, ref forward, ref up, out result);
}
/// <summary>
/// Creates a left-handed, look-at quaternion.
/// </summary>
/// <param name="forward">The camera's forward direction.</param>
/// <returns>The created look-at quaternion.</returns>
public static Quaternion RotationLookAt(Vector3 forward)
{
return RotationLookAt(forward, Vector3.Up);
}
/// <summary>
/// Creates a left-handed, look-at quaternion.
/// </summary>
@@ -1005,6 +1026,16 @@ namespace FlaxEngine
return result;
}
/// <summary>
/// Creates a rotation with the specified forward and upwards directions.
/// </summary>
/// <param name="forward">The forward direction. Direction to orient towards.</param>
/// <returns>The calculated quaternion.</returns>
public static Quaternion LookRotation(Vector3 forward)
{
return LookRotation(forward, Vector3.Up);
}
/// <summary>
/// Creates a rotation with the specified forward and upwards directions.
/// </summary>

View File

@@ -833,6 +833,55 @@ namespace FlaxEngine
return value;
}
/// <summary>
/// Makes sure that Length of the output vector is always below max and above 0.
/// </summary>
/// <param name="vector">Input Vector.</param>
/// <param name="max">Max Length</param>
public static Vector2 ClampLength(Vector2 vector, float max)
{
return ClampLength(vector, 0, max);
}
/// <summary>
/// Makes sure that Length of the output vector is always below max and above min.
/// </summary>
/// <param name="vector">Input Vector.</param>
/// <param name="min">Min Length</param>
/// <param name="max">Max Length</param>
public static Vector2 ClampLength(Vector2 vector, float min, float max)
{
ClampLength(ref vector, min, max, out Vector2 retVect);
return retVect;
}
/// <summary>
/// Makes sure that Length of the output vector is always below max and above min.
/// </summary>
/// <param name="vector">Input Vector.</param>
/// <param name="min">Min Length</param>
/// <param name="max">Max Length</param>
/// <param name="retVect">The Return Vector</param>
public static void ClampLength(ref Vector2 vector, float min, float max, out Vector2 retVect)
{
retVect.X = vector.X;
retVect.Y = vector.Y;
float lenSq = retVect.LengthSquared;
if (lenSq > max * max)
{
float scaleFactor = max / (float)Math.Sqrt(lenSq);
retVect.X = retVect.X * scaleFactor;
retVect.Y = retVect.Y * scaleFactor;
}
if (lenSq < min * min)
{
float scaleFactor = min / (float)Math.Sqrt(lenSq);
retVect.X = retVect.X * scaleFactor;
retVect.Y = retVect.Y * scaleFactor;
}
}
/// <summary>
/// Returns the vector with components rounded to the nearest integer.
/// </summary>

View File

@@ -992,6 +992,58 @@ namespace FlaxEngine
return value;
}
/// <summary>
/// Makes sure that Length of the output vector is always below max and above 0.
/// </summary>
/// <param name="vector">Input Vector.</param>
/// <param name="max">Max Length</param>
public static Vector3 ClampLength(Vector3 vector, float max)
{
return ClampLength(vector, 0, max);
}
/// <summary>
/// Makes sure that Length of the output vector is always below max and above min.
/// </summary>
/// <param name="vector">Input Vector.</param>
/// <param name="min">Min Length</param>
/// <param name="max">Max Length</param>
public static Vector3 ClampLength(Vector3 vector, float min, float max)
{
ClampLength(ref vector, min, max, out Vector3 retVect);
return retVect;
}
/// <summary>
/// Makes sure that Length of the output vector is always below max and above min.
/// </summary>
/// <param name="vector">Input Vector.</param>
/// <param name="min">Min Length</param>
/// <param name="max">Max Length</param>
/// <param name="retVect">The Return Vector</param>
public static void ClampLength(ref Vector3 vector, float min, float max, out Vector3 retVect)
{
retVect.X = vector.X;
retVect.Y = vector.Y;
retVect.Z = vector.Z;
float lenSq = retVect.LengthSquared;
if (lenSq > max * max)
{
float scaleFactor = max / (float)Math.Sqrt(lenSq);
retVect.X = retVect.X * scaleFactor;
retVect.Y = retVect.Y * scaleFactor;
retVect.Z = retVect.Z * scaleFactor;
}
if (lenSq < min * min)
{
float scaleFactor = min / (float)Math.Sqrt(lenSq);
retVect.X = retVect.X * scaleFactor;
retVect.Y = retVect.Y * scaleFactor;
retVect.Z = retVect.Z * scaleFactor;
}
}
/// <summary>
/// Performs a linear interpolation between two vectors.
/// </summary>

View File

@@ -792,6 +792,61 @@ namespace FlaxEngine
return value;
}
/// <summary>
/// Makes sure that Length of the output vector is always below max and above 0.
/// </summary>
/// <param name="vector">Input Vector.</param>
/// <param name="max">Max Length</param>
public static Vector4 ClampLength(Vector4 vector, float max)
{
return ClampLength(vector, 0, max);
}
/// <summary>
/// Makes sure that Length of the output vector is always below max and above min.
/// </summary>
/// <param name="vector">Input Vector.</param>
/// <param name="min">Min Length</param>
/// <param name="max">Max Length</param>
public static Vector4 ClampLength(Vector4 vector, float min, float max)
{
ClampLength(ref vector, min, max, out Vector4 retVect);
return retVect;
}
/// <summary>
/// Makes sure that Length of the output vector is always below max and above min.
/// </summary>
/// <param name="vector">Input Vector.</param>
/// <param name="min">Min Length</param>
/// <param name="max">Max Length</param>
/// <param name="retVect">The Return Vector</param>
public static void ClampLength(ref Vector4 vector, float min, float max, out Vector4 retVect)
{
retVect.X = vector.X;
retVect.Y = vector.Y;
retVect.Z = vector.Z;
retVect.W = vector.W;
float lenSq = retVect.LengthSquared;
if (lenSq > max * max)
{
float scaleFactor = max / (float)Math.Sqrt(lenSq);
retVect.X = retVect.X * scaleFactor;
retVect.Y = retVect.Y * scaleFactor;
retVect.Z = retVect.Z * scaleFactor;
retVect.W = retVect.W * scaleFactor;
}
if (lenSq < min * min)
{
float scaleFactor = min / (float)Math.Sqrt(lenSq);
retVect.X = retVect.X * scaleFactor;
retVect.Y = retVect.Y * scaleFactor;
retVect.Z = retVect.Z * scaleFactor;
retVect.W = retVect.W * scaleFactor;
}
}
/// <summary>
/// Performs a linear interpolation between two vectors.
/// </summary>

View File

@@ -1,12 +1,7 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#include "DebugLog.h"
#include "Engine/Core/Log.h"
#include "Engine/Scripting/InternalCalls.h"
#include "Engine/Scripting/ScriptingObject.h"
#include "Engine/Scripting/MException.h"
#include "Engine/Scripting/Scripting.h"
#include "Engine/Scripting/ScriptingType.h"
#include "Engine/Scripting/BinaryModule.h"
#include "Engine/Scripting/MainThreadManagedInvokeAction.h"
#include "Engine/Scripting/ManagedCLR/MDomain.h"
@@ -16,70 +11,7 @@
#include <ThirdParty/mono-2.0/mono/metadata/exception.h>
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
namespace DebugLogHandlerInternal
{
void LogWrite(LogType level, MonoString* msgObj)
{
StringView msg;
MUtils::ToString(msgObj, msg);
Log::Logger::Write(level, msg);
}
void Log(LogType level, MonoString* msgObj, ScriptingObject* obj, MonoString* stackTrace)
{
if (msgObj == nullptr)
return;
// Get info
StringView msg;
MUtils::ToString(msgObj, msg);
//const String objName = obj ? obj->ToString() : String::Empty;
// Send event
// TODO: maybe option for build to threat warnings and errors as fatal errors?
//const String logMessage = String::Format(TEXT("Debug:{1} {2}"), objName, *msg);
Log::Logger::Write(level, msg);
}
void LogException(MonoException* exception, ScriptingObject* obj)
{
if (exception == nullptr)
return;
// Get info
MException ex(exception);
String objName = obj ? obj->ToString() : String::Empty;
// Print exception including inner exceptions
// TODO: maybe option for build to threat warnings and errors as fatal errors?
ex.Log(LogType::Warning, objName.GetText());
}
}
namespace FlaxLogWriterInternal
{
void WriteStringToLog(MonoString* msg)
{
if (msg == nullptr)
return;
auto msgStr = (Char*)mono_string_to_utf16(msg);
LOG_STR(Info, msgStr);
}
}
void DebugLog::RegisterInternalCalls()
{
// DebugLogHandler
ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_LogWrite", &DebugLogHandlerInternal::LogWrite);
ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_Log", &DebugLogHandlerInternal::Log);
ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_LogException", &DebugLogHandlerInternal::LogException);
// FlaxLogWriter
ADD_INTERNAL_CALL("FlaxEngine.FlaxLogWriter::Internal_WriteStringToLog", &FlaxLogWriterInternal::WriteStringToLog);
}
namespace DebugLogImpl
namespace Impl
{
MMethod* Internal_SendLog = nullptr;
MMethod* Internal_SendLogException = nullptr;
@@ -87,7 +19,7 @@ namespace DebugLogImpl
CriticalSection Locker;
}
using namespace DebugLogImpl;
using namespace Impl;
void ClearMethods(MAssembly*)
{
@@ -111,7 +43,7 @@ bool CacheMethods()
if (!debugLogHandlerClass)
return false;
Internal_SendLog = debugLogHandlerClass->GetMethod("Internal_SendLog", 2);
Internal_SendLog = debugLogHandlerClass->GetMethod("Internal_SendLog", 3);
if (!Internal_SendLog)
return false;
@@ -128,7 +60,7 @@ bool CacheMethods()
return false;
}
void DebugLog::Log(LogType type, const String& message)
void DebugLog::Log(LogType type, const StringView& message)
{
if (CacheMethods())
return;
@@ -137,15 +69,18 @@ void DebugLog::Log(LogType type, const String& message)
MainThreadManagedInvokeAction::ParamsBuilder params;
params.AddParam(type);
params.AddParam(message, scriptsDomain->GetNative());
#if BUILD_RELEASE
params.AddParam(StringView::Empty, scriptsDomain->GetNative());
#else
const String stackTrace = Platform::GetStackTrace(1);
params.AddParam(stackTrace, scriptsDomain->GetNative());
#endif
MainThreadManagedInvokeAction::Invoke(Internal_SendLog, params);
}
void DebugLog::LogException(MonoObject* exceptionObject)
{
if (exceptionObject == nullptr)
return;
if (CacheMethods())
if (exceptionObject == nullptr || CacheMethods())
return;
MainThreadManagedInvokeAction::ParamsBuilder params;

View File

@@ -10,13 +10,6 @@
/// </summary>
class FLAXENGINE_API DebugLog
{
public:
/// <summary>
/// Registers the internal calls to managed code.
/// </summary>
static void RegisterInternalCalls();
public:
/// <summary>
@@ -24,13 +17,13 @@ public:
/// </summary>
/// <param name="type">The message type.</param>
/// <param name="message">The message.</param>
static void Log(LogType type, const String& message);
static void Log(LogType type, const StringView& message);
/// <summary>
/// A variant of Debug.Log that logs a warning message to the console.
/// </summary>
/// <param name="message">The text message to display.</param>
FORCE_INLINE static void Log(const String& message)
FORCE_INLINE static void Log(const StringView& message)
{
Log(LogType::Info, message);
}
@@ -39,7 +32,7 @@ public:
/// A variant of Debug.Log that logs a warning message to the console.
/// </summary>
/// <param name="message">The text message to display.</param>
FORCE_INLINE static void LogWarning(const String& message)
FORCE_INLINE static void LogWarning(const StringView& message)
{
Log(LogType::Warning, message);
}
@@ -48,7 +41,7 @@ public:
/// A variant of Debug.Log that logs a error message to the console.
/// </summary>
/// <param name="message">The text message to display.</param>
FORCE_INLINE static void LogError(const String& message)
FORCE_INLINE static void LogError(const StringView& message)
{
Log(LogType::Error, message);
}

View File

@@ -36,19 +36,27 @@ namespace FlaxEngine
/// <inheritdoc />
public void Log(LogType logType, Object context, string message)
{
#if DEBUG
string stackTrace = Environment.StackTrace;
if (message == null)
return;
#if BUILD_RELEASE
string stackTrace = null;
#else
string stackTrace = string.Empty;
string stackTrace = Environment.StackTrace;
#endif
Internal_Log(logType, message, Object.GetUnmanagedPtr(context), stackTrace);
SendLog?.Invoke(logType, message, context, stackTrace);
}
internal static void Internal_SendLog(LogType type, string message)
internal static void Internal_SendLog(LogType logType, string message, string stackTrace)
{
Debug.Logger.Log(type, message);
if (message == null)
return;
var logger = Debug.Logger;
if (logger.IsLogTypeAllowed(logType))
{
Internal_Log(logType, message, IntPtr.Zero, stackTrace);
((DebugLogHandler)logger.LogHandler).SendLog?.Invoke(logType, message, null, stackTrace);
}
}
internal static void Internal_SendLogException(Exception exception)

View File

@@ -202,11 +202,11 @@ void PlatformBase::Fatal(const Char* msg, void* context)
LOG(Error, "");
// Log stack trace
const auto stackTrace = Platform::GetStackTrace(context ? 0 : 1, 60, context);
if (stackTrace.HasItems())
const auto stackFrames = Platform::GetStackFrames(context ? 0 : 1, 60, context);
if (stackFrames.HasItems())
{
LOG(Error, "Stack trace:");
for (const auto& frame : stackTrace)
for (const auto& frame : stackFrames)
{
char chr = 0;
int32 num = StringUtils::Length(frame.ModuleName);
@@ -217,11 +217,11 @@ void PlatformBase::Fatal(const Char* msg, void* context)
if (StringUtils::Length(frame.FileName) != 0)
{
StringAsUTF16<ARRAY_COUNT(StackFrame::FileName)> fileName(frame.FileName);
LOG(Error, " at {0}!{1} in {2}:line {3}", moduleName.Get(), functionName.Get(), fileName.Get(), frame.LineNumber);
LOG(Error, " at {0}!{1}() in {2}:line {3}", moduleName.Get(), functionName.Get(), fileName.Get(), frame.LineNumber);
}
else if (StringUtils::Length(frame.FunctionName) != 0)
{
LOG(Error, " at {0}::{1}", moduleName.Get(), functionName.Get());
LOG(Error, " at {0}!{1}()", moduleName.Get(), functionName.Get());
}
else if (StringUtils::Length(frame.ModuleName) != 0)
{
@@ -483,11 +483,35 @@ int32 PlatformBase::RunProcess(const StringView& cmdLine, const StringView& work
return -1;
}
Array<PlatformBase::StackFrame> PlatformBase::GetStackTrace(int32 skipCount, int32 maxDepth, void* context)
Array<PlatformBase::StackFrame> PlatformBase::GetStackFrames(int32 skipCount, int32 maxDepth, void* context)
{
return Array<StackFrame>();
}
String PlatformBase::GetStackTrace(int32 skipCount, int32 maxDepth, void* context)
{
StringBuilder result;
Array<StackFrame> stackFrames = Platform::GetStackFrames(skipCount, maxDepth, context);
for (const auto& frame : stackFrames)
{
StringAsUTF16<ARRAY_COUNT(StackFrame::FunctionName)> functionName(frame.FunctionName);
if (StringUtils::Length(frame.FileName) != 0)
{
StringAsUTF16<ARRAY_COUNT(StackFrame::FileName)> fileName(frame.FileName);
result.AppendFormat(TEXT(" at {0}() in {1}:line {2}\n"), functionName.Get(), fileName.Get(), frame.LineNumber);
}
else if (StringUtils::Length(frame.FunctionName) != 0)
{
result.AppendFormat(TEXT(" at {0}()\n"), functionName.Get());
}
else
{
result.AppendFormat(TEXT(" at 0x{0:x}\n"), (uint64)frame.ProgramCounter);
}
}
return result.ToString();
}
void PlatformBase::CollectCrashData(const String& crashDataFolder, void* context)
{
}

View File

@@ -804,7 +804,16 @@ public:
/// <param name="maxDepth">The maximum depth of the stack to collect. Can be used to prevent too long stack traces in case of stack overflow exception.</param>
/// <param name="context">The platform-dependent context for the stack trace collecting (eg. platform exception info).</param>
/// <returns>The collected stack trace frames. Empty if not supported (eg. platform not implements this feature or not supported in the distributed build).</returns>
static Array<StackFrame, HeapAllocation> GetStackTrace(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr);
static Array<StackFrame, HeapAllocation> GetStackFrames(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr);
/// <summary>
/// Gets current native stack trace information as string.
/// </summary>
/// <param name="skipCount">The amount of stack frames to skip from the beginning. Can be used to skip the callee function from the trace (eg. in crash handler).</param>
/// <param name="maxDepth">The maximum depth of the stack to collect. Can be used to prevent too long stack traces in case of stack overflow exception.</param>
/// <param name="context">The platform-dependent context for the stack trace collecting (eg. platform exception info).</param>
/// <returns>The collected stack trace printed into string. Empty if not supported (eg. platform not implements this feature or not supported in the distributed build).</returns>
static String GetStackTrace(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr);
// Crash dump data handling
static void CollectCrashData(const String& crashDataFolder, void* context = nullptr);

View File

@@ -6,6 +6,7 @@
#include "Engine/Engine/Engine.h"
#include "Engine/Platform/MessageBox.h"
#include "Engine/Profiler/ProfilerCPU.h"
#include "Engine/Platform/BatteryInfo.h"
#include "Engine/Input/Input.h"
#include "Engine/Core/Log.h"
#include "UWPWindow.h"
@@ -114,6 +115,21 @@ void UWPPlatform::Exit()
Win32Platform::Exit();
}
BatteryInfo UWPPlatform::GetBatteryInfo()
{
BatteryInfo info;
SYSTEM_POWER_STATUS status;
GetSystemPowerStatus(&status);
info.BatteryLifePercent = (float)status.BatteryLifePercent / 255.0f;
if (status.BatteryFlag & 8)
info.State = BatteryInfo::States::BatteryCharging;
else if (status.BatteryFlag & 1 || status.BatteryFlag & 2 || status.BatteryFlag & 4)
info.State = BatteryInfo::States::BatteryDischarging;
else if (status.ACLineStatus == 1 || status.BatteryFlag & 128)
info.State = BatteryInfo::States::Connected;
return info;
}
int32 UWPPlatform::GetDpi()
{
return SystemDpi;

View File

@@ -30,6 +30,7 @@ public:
static void Tick();
static void BeforeExit();
static void Exit();
static BatteryInfo GetBatteryInfo();
static int32 GetDpi();
static String GetUserLocaleName();
static String GetComputerName();

View File

@@ -5,7 +5,6 @@
#include "Engine/Platform/Platform.h"
#include "Engine/Platform/MemoryStats.h"
#include "Engine/Platform/CPUInfo.h"
#include "Engine/Platform/BatteryInfo.h"
#include "Engine/Core/Types/Guid.h"
#include "Engine/Core/Types/String.h"
#include "Engine/Core/Math/Math.h"
@@ -341,21 +340,6 @@ bool Win32Platform::Is64BitPlatform()
#endif
}
BatteryInfo Win32Platform::GetBatteryInfo()
{
BatteryInfo info;
SYSTEM_POWER_STATUS status;
GetSystemPowerStatus(&status);
info.BatteryLifePercent = (float)status.BatteryLifePercent / 255.0f;
if (status.BatteryFlag & 8)
info.State = BatteryInfo::States::BatteryCharging;
else if (status.BatteryFlag & 1 || status.BatteryFlag & 2 || status.BatteryFlag & 4)
info.State = BatteryInfo::States::BatteryDischarging;
else if (status.ACLineStatus == 1 || status.BatteryFlag & 128)
info.State = BatteryInfo::States::Connected;
return info;
}
CPUInfo Win32Platform::GetCPUInfo()
{
return CpuInfo;

View File

@@ -33,7 +33,6 @@ public:
static void* AllocatePages(uint64 numPages, uint64 pageSize);
static void FreePages(void* ptr);
static bool Is64BitPlatform();
static BatteryInfo GetBatteryInfo();
static CPUInfo GetCPUInfo();
static int32 GetCacheLineSize();
static MemoryStats GetMemoryStats();

View File

@@ -7,6 +7,7 @@
#include "Engine/Platform/CreateWindowSettings.h"
#include "Engine/Platform/WindowsManager.h"
#include "Engine/Platform/MemoryStats.h"
#include "Engine/Platform/BatteryInfo.h"
#include "Engine/Engine/Globals.h"
#include "Engine/Core/Log.h"
#include "Engine/Core/Collections/Dictionary.h"
@@ -680,6 +681,21 @@ void WindowsPlatform::SetHighDpiAwarenessEnabled(bool enable)
FreeLibrary(shCoreDll);
}
BatteryInfo WindowsPlatform::GetBatteryInfo()
{
BatteryInfo info;
SYSTEM_POWER_STATUS status;
GetSystemPowerStatus(&status);
info.BatteryLifePercent = (float)status.BatteryLifePercent / 255.0f;
if (status.BatteryFlag & 8)
info.State = BatteryInfo::States::BatteryCharging;
else if (status.BatteryFlag & 1 || status.BatteryFlag & 2 || status.BatteryFlag & 4)
info.State = BatteryInfo::States::BatteryDischarging;
else if (status.ACLineStatus == 1 || status.BatteryFlag & 128)
info.State = BatteryInfo::States::Connected;
return info;
}
int32 WindowsPlatform::GetDpi()
{
return SystemDpi;
@@ -1107,7 +1123,7 @@ void* WindowsPlatform::LoadLibrary(const Char* filename)
return handle;
}
Array<PlatformBase::StackFrame> WindowsPlatform::GetStackTrace(int32 skipCount, int32 maxDepth, void* context)
Array<PlatformBase::StackFrame> WindowsPlatform::GetStackFrames(int32 skipCount, int32 maxDepth, void* context)
{
Array<StackFrame> result;
#if CRASH_LOG_ENABLE

View File

@@ -64,6 +64,7 @@ public:
static bool IsDebuggerPresent();
#endif
static void SetHighDpiAwarenessEnabled(bool enable);
static BatteryInfo GetBatteryInfo();
static int32 GetDpi();
static String GetUserLocaleName();
static String GetComputerName();
@@ -82,7 +83,7 @@ public:
static int32 RunProcess(const StringView& cmdLine, const StringView& workingDir, const Dictionary<String, String>& environment, bool hiddenWindow = true);
static Window* CreateWindow(const CreateWindowSettings& settings);
static void* LoadLibrary(const Char* filename);
static Array<StackFrame, HeapAllocation> GetStackTrace(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr);
static Array<StackFrame, HeapAllocation> GetStackFrames(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr);
#if CRASH_LOG_ENABLE
static void CollectCrashData(const String& crashDataFolder, void* context = nullptr);
#endif

View File

@@ -1,9 +1,10 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#include "Engine/Platform/FileSystem.h"
#include "Engine/Debug/DebugLog.h"
#include "Engine/Animations/Graph/AnimGraph.h"
#include "Engine/Scripting/InternalCalls.h"
#include "Engine/Scripting/MException.h"
#include "Engine/Scripting/ManagedCLR/MUtils.h"
namespace UtilsInternal
{
@@ -13,9 +14,64 @@ namespace UtilsInternal
}
}
namespace DebugLogHandlerInternal
{
void LogWrite(LogType level, MonoString* msgObj)
{
StringView msg;
MUtils::ToString(msgObj, msg);
Log::Logger::Write(level, msg);
}
void Log(LogType level, MonoString* msgObj, ScriptingObject* obj, MonoString* stackTrace)
{
if (msgObj == nullptr)
return;
// Get info
StringView msg;
MUtils::ToString(msgObj, msg);
//const String objName = obj ? obj->ToString() : String::Empty;
// Send event
// TODO: maybe option for build to threat warnings and errors as fatal errors?
//const String logMessage = String::Format(TEXT("Debug:{1} {2}"), objName, *msg);
Log::Logger::Write(level, msg);
}
void LogException(MonoException* exception, ScriptingObject* obj)
{
if (exception == nullptr)
return;
// Get info
MException ex(exception);
const String objName = obj ? obj->ToString() : String::Empty;
// Print exception including inner exceptions
// TODO: maybe option for build to threat warnings and errors as fatal errors?
ex.Log(LogType::Warning, objName.GetText());
}
}
namespace FlaxLogWriterInternal
{
void WriteStringToLog(MonoString* msgObj)
{
if (msgObj == nullptr)
return;
StringView msg;
MUtils::ToString(msgObj, msg);
LOG_STR(Info, msg);
}
}
void registerFlaxEngineInternalCalls()
{
DebugLog::RegisterInternalCalls();
AnimGraphExecutor::initRuntime();
ADD_INTERNAL_CALL("FlaxEngine.Utils::MemoryCopy", &UtilsInternal::MemoryCopy);
ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_LogWrite", &DebugLogHandlerInternal::LogWrite);
ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_Log", &DebugLogHandlerInternal::Log);
ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_LogException", &DebugLogHandlerInternal::LogException);
ADD_INTERNAL_CALL("FlaxEngine.FlaxLogWriter::Internal_WriteStringToLog", &FlaxLogWriterInternal::WriteStringToLog);
}

View File

@@ -77,12 +77,24 @@ public:
AddParam(val);
}
FORCE_INLINE void AddParam(const StringView& value)
{
MonoString* val = MUtils::ToString(value);
AddParam(val);
}
FORCE_INLINE void AddParam(const String& value, MonoDomain* domain)
{
MonoString* val = MUtils::ToString(value, domain);
AddParam(val);
}
FORCE_INLINE void AddParam(const StringView& value, MonoDomain* domain)
{
MonoString* val = MUtils::ToString(value, domain);
AddParam(val);
}
void GetParams(void* params[8])
{
for (int32 i = 0; i < Count; i++)

View File

@@ -148,9 +148,11 @@ namespace FlaxEngine
/// </summary>
internal static void Init()
{
#if DEBUG
#if BUILD_DEBUG
Debug.Logger.LogHandler.LogWrite(LogType.Info, "Using FlaxAPI in Debug");
#else
#elif BUILD_DEVELOPMENT
Debug.Logger.LogHandler.LogWrite(LogType.Info, "Using FlaxAPI in Development");
#elif BUILD_RELEASE
Debug.Logger.LogHandler.LogWrite(LogType.Info, "Using FlaxAPI in Release");
#endif

View File

@@ -271,7 +271,7 @@ void MaterialGenerator::prepareLayer(MaterialLayer* layer, bool allowVisiblePara
mp.Type = MaterialParameterType::Texture;
// Special case for Normal Maps
auto asset = Content::LoadAsync<Texture>((Guid)param->Value);
auto asset = (Texture*)::LoadAsset((Guid)param->Value, Texture::TypeInitializer);
if (asset && !asset->WaitForLoaded() && asset->IsNormalMap())
mp.Type = MaterialParameterType::NormalMap;
}

View File

@@ -6,7 +6,7 @@
#include "Engine/Graphics/Materials/MaterialInfo.h"
#include "Engine/Graphics/Materials/MaterialParams.h"
#include "Engine/Content/Utilities/AssetsContainer.h"
#include "Engine/Content/AssetsContainer.h"
#include "MaterialLayer.h"
#include "Types.h"

View File

@@ -10,7 +10,7 @@
#include "Engine/Core/Collections/HashSet.h"
#include "Engine/Utilities/TextWriter.h"
#include "Engine/Graphics/Materials/MaterialParams.h"
#include "Engine/Content/Utilities/AssetsContainer.h"
#include "Engine/Content/AssetsContainer.h"
#include "Engine/Animations/Curve.h"
#define SHADER_GRAPH_MAX_CALL_STACK 100

View File

@@ -723,7 +723,7 @@ void VisjectExecutor::ProcessGroupTools(Box* box, Node* node, Value& value)
// Asset Reference
case 18:
{
value = Content::LoadAsync<Asset>((Guid)node->Values[0]);
value = ::LoadAsset((Guid)node->Values[0], Asset::TypeInitializer);
break;
}
// To String

View File

@@ -8,7 +8,7 @@
#include "Engine/Core/Math/Vector4.h"
#include "Engine/Content/Asset.h"
#include "Engine/Content/AssetReference.h"
#include "Engine/Content/Utilities/AssetsContainer.h"
#include "Engine/Content/AssetsContainer.h"
#include "Engine/Animations/Curve.h"
#define VISJECT_GRAPH_NODE_MAX_ASSETS 14
@@ -204,7 +204,7 @@ public:
// Get Gameplay Global
case 16:
{
n->Assets[0] = Content::LoadAsync<Asset>((Guid)n->Values[0]);
n->Assets[0] = ::LoadAsset((Guid)n->Values[0], Asset::TypeInitializer);
break;
}
}