mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Better engine exception for scripting
This commit is contained in:
@@ -259,7 +259,8 @@ class LogWindow : EditorWindow
|
|||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
if (ImGui.BeginChild("Message", .Zero, .None, .None))
|
ImGui.BeginGroup();
|
||||||
|
|
||||||
{
|
{
|
||||||
// Timestamp
|
// Timestamp
|
||||||
ImGui.TextWrapped($"[{message.Timestamp:HH:mm:ss.fff}]");
|
ImGui.TextWrapped($"[{message.Timestamp:HH:mm:ss.fff}]");
|
||||||
@@ -310,7 +311,7 @@ class LogWindow : EditorWindow
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.EndChild();
|
ImGui.EndGroup();
|
||||||
|
|
||||||
if (ImGui.IsItemHovered() && ImGui.IsMouseDoubleClicked(.Left))
|
if (ImGui.IsItemHovered() && ImGui.IsMouseDoubleClicked(.Left))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -513,7 +513,7 @@ static class ScriptEngine
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.ClientLogger.Error($"Mono Exception \"{exception.FullName}\": \"{exception.Message}\"{entityInfo}\nStackTrace:\n{exception.StackTrace}", exception);
|
Log.ClientLogger.Error($"Exception \"{exception.FullName}\": \"{exception.Message}\"{entityInfo}\nStackTrace:\n{exception.StackTrace}", exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Wrap like the other classes
|
// TODO: Wrap like the other classes
|
||||||
|
|||||||
+2
-2
@@ -31,8 +31,8 @@ public class ScriptException
|
|||||||
public this(UUID entityId, StringView fullExceptionClassName, StringView message, StringView stackTrace)
|
public this(UUID entityId, StringView fullExceptionClassName, StringView message, StringView stackTrace)
|
||||||
{
|
{
|
||||||
String allocFullExceptionClassName = append String(fullExceptionClassName);
|
String allocFullExceptionClassName = append String(fullExceptionClassName);
|
||||||
String allocMessage = append String(fullExceptionClassName);
|
String allocMessage = append String(message);
|
||||||
String allocStackTrace = append String(fullExceptionClassName);
|
String allocStackTrace = append String(stackTrace);
|
||||||
|
|
||||||
_fullName = allocFullExceptionClassName;
|
_fullName = allocFullExceptionClassName;
|
||||||
_message = allocMessage;
|
_message = allocMessage;
|
||||||
@@ -224,6 +224,8 @@ static class ScriptGlue
|
|||||||
private function void SetEngineFunctions(EngineFunctions* engineFunctions);
|
private function void SetEngineFunctions(EngineFunctions* engineFunctions);
|
||||||
private static SetEngineFunctions _setEngineFunctions;
|
private static SetEngineFunctions _setEngineFunctions;
|
||||||
|
|
||||||
|
private static String _lastExceptionMessage = new .() ~ delete _;
|
||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
{
|
||||||
if (_setEngineFunctions == null)
|
if (_setEngineFunctions == null)
|
||||||
@@ -389,16 +391,29 @@ static class ScriptGlue
|
|||||||
|
|
||||||
public enum EngineResult : int32
|
public enum EngineResult : int32
|
||||||
{
|
{
|
||||||
Ok = 0, // Success, for boolean return value means True
|
case Ok = 0; // Success, for boolean return value means True
|
||||||
False = 1, // Success, for boolean return value means False
|
case False = 1; // Success, for boolean return value means False
|
||||||
Error = -1,
|
case Error = -1;
|
||||||
NotImplemented = -2,
|
case NotImplemented = -2;
|
||||||
ArgumentError = -3,
|
case ArgumentError = -3;
|
||||||
|
|
||||||
// Entity Errors:
|
// Entity Errors:
|
||||||
EntityNotFound = -4, // The entity doesn't exist or was deleted.
|
case EntityNotFound = -4; // The entity doesn't exist or was deleted.
|
||||||
EntityDoesntHaveComponent = -5, // The entity has no component of type {typeof(T)} or it was deleted.
|
case EntityDoesntHaveComponent = -5; // The entity has no component of type {typeof(T)} or it was deleted.
|
||||||
AssetNotFound = -6, // No asset exists for AssetHandle \"{assetId}\".
|
case AssetNotFound = -6; // No asset exists for AssetHandle \"{assetId}\".
|
||||||
|
|
||||||
|
case CustomError = 1 << 31;
|
||||||
|
|
||||||
|
public static EngineResult CustomError(int32 payload)
|
||||||
|
{
|
||||||
|
return CustomError | payload;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[RegisterCall]
|
||||||
|
static char8* GetLastExceptionMessage()
|
||||||
|
{
|
||||||
|
return _lastExceptionMessage.Length == 0 ? null : _lastExceptionMessage.CStr();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Log
|
#region Log
|
||||||
@@ -1492,6 +1507,11 @@ static class ScriptGlue
|
|||||||
asset
|
asset
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
static void SetExceptionMessage(StringView message)
|
||||||
|
{
|
||||||
|
_lastExceptionMessage.Set(message);
|
||||||
|
}
|
||||||
|
|
||||||
static mixin GetAssetOrReturn<T>(UUID assetId) where T : Asset
|
static mixin GetAssetOrReturn<T>(UUID assetId) where T : Asset
|
||||||
{
|
{
|
||||||
AssetHandle handle = .(assetId);
|
AssetHandle handle = .(assetId);
|
||||||
@@ -1499,6 +1519,7 @@ static class ScriptGlue
|
|||||||
|
|
||||||
if (asset == null)
|
if (asset == null)
|
||||||
{
|
{
|
||||||
|
SetExceptionMessage(scope $"Asset (Id: {assetId}) not found.");
|
||||||
return EngineResult.AssetNotFound;
|
return EngineResult.AssetNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1511,6 +1532,7 @@ static class ScriptGlue
|
|||||||
|
|
||||||
if (asset == null)
|
if (asset == null)
|
||||||
{
|
{
|
||||||
|
SetExceptionMessage(scope $"Asset (Handle: {assetHandle}) not found.");
|
||||||
return EngineResult.AssetNotFound;
|
return EngineResult.AssetNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1552,7 +1574,26 @@ static class ScriptGlue
|
|||||||
{
|
{
|
||||||
Material material = GetAssetOrReturn!<Material>(assetHandle);
|
Material material = GetAssetOrReturn!<Material>(assetHandle);
|
||||||
|
|
||||||
material.[Friend]SetVariableRaw(StringView(variableName), elementType, rows, columns , arrayLength, Span<uint8>((uint8*)rawData, dataLength));
|
StringView variableNameView = StringView(variableName);
|
||||||
|
|
||||||
|
if (material.[Friend]SetVariableRaw(variableNameView, elementType, rows, columns , arrayLength, Span<uint8>((uint8*)rawData, dataLength)) case .Err(let error))
|
||||||
|
{
|
||||||
|
switch (error)
|
||||||
|
{
|
||||||
|
case .VariableNotFound:
|
||||||
|
SetExceptionMessage(scope $"Material \"{material.Identifier}\" has no variable \"{variableNameView}\".");
|
||||||
|
return .ArgumentError;
|
||||||
|
case .ElementTypeMismatch:
|
||||||
|
SetExceptionMessage(scope $"Variable \"{variableNameView}\" has incompatible element type.");
|
||||||
|
return .ArgumentError;
|
||||||
|
case .MatrixDimensionMismatch:
|
||||||
|
SetExceptionMessage(scope $"Variable \"{variableNameView}\" has incompatible matrix dimension type.");
|
||||||
|
return .ArgumentError;
|
||||||
|
case .ProvidedBufferTooShort:
|
||||||
|
SetExceptionMessage(scope $"The provided data buffer for variable \"{variableNameView}\" is not large enough.");
|
||||||
|
}
|
||||||
|
return .Error;
|
||||||
|
}
|
||||||
|
|
||||||
return .Ok;
|
return .Ok;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,24 +17,16 @@ internal enum EngineResult
|
|||||||
EntityNotFound = -4, // The entity doesn't exist or was deleted.
|
EntityNotFound = -4, // The entity doesn't exist or was deleted.
|
||||||
EntityDoesntHaveComponent = -5, // The entity has no component of type {typeof(T)} or it was deleted.
|
EntityDoesntHaveComponent = -5, // The entity has no component of type {typeof(T)} or it was deleted.
|
||||||
AssetNotFound = -6, // No asset exists for AssetHandle \"{assetId}\".
|
AssetNotFound = -6, // No asset exists for AssetHandle \"{assetId}\".
|
||||||
|
CustomError = 1 << 31
|
||||||
}
|
}
|
||||||
|
|
||||||
public class EngineException(string message) : Exception(message);
|
public class EngineException(string message) : Exception(message);
|
||||||
|
|
||||||
public class EntityNotFoundException : Exception
|
public class EntityNotFoundException(string? message = null) : Exception(message);
|
||||||
{
|
|
||||||
|
|
||||||
}
|
public class ComponentNotFoundException(string? message = null) : Exception(message);
|
||||||
|
|
||||||
public class ComponentNotFoundException : Exception
|
public class AssetNotFoundException(string? message = null) : Exception(message);
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AssetNotFoundException : Exception
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static class EngineErrors
|
internal static class EngineErrors
|
||||||
{
|
{
|
||||||
@@ -43,22 +35,24 @@ internal static class EngineErrors
|
|||||||
if (result >= 0)
|
if (result >= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
string engineMessage = ScriptGlue.GetLastExceptionMessage();
|
||||||
|
|
||||||
switch (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
case EngineResult.Error:
|
case EngineResult.Error:
|
||||||
throw new EngineException($"Unspecified engine excepiton in {callerName}");
|
throw new EngineException(engineMessage ?? $"Unspecified engine excepiton in {callerName}");
|
||||||
case EngineResult.NotImplemented:
|
case EngineResult.NotImplemented:
|
||||||
throw new NotImplementedException($"Function {callerName} is not implemented in the engine.");
|
throw new NotImplementedException(engineMessage ?? $"Function {callerName} is not implemented in the engine.");
|
||||||
case EngineResult.ArgumentError:
|
case EngineResult.ArgumentError:
|
||||||
throw new ArgumentException($"An argument passed to {callerName} is invalid.");
|
throw new ArgumentException(engineMessage ?? $"An argument passed to {callerName} is invalid.");
|
||||||
case EngineResult.EntityNotFound:
|
case EngineResult.EntityNotFound:
|
||||||
throw new EntityNotFoundException();
|
throw new EntityNotFoundException(engineMessage);
|
||||||
case EngineResult.EntityDoesntHaveComponent:
|
case EngineResult.EntityDoesntHaveComponent:
|
||||||
throw new ComponentNotFoundException();
|
throw new ComponentNotFoundException(engineMessage);
|
||||||
case EngineResult.AssetNotFound:
|
case EngineResult.AssetNotFound:
|
||||||
throw new AssetNotFoundException();
|
throw new AssetNotFoundException(engineMessage);
|
||||||
default:
|
default:
|
||||||
throw new EngineException($"Unknown engine excepiton in {callerName}");
|
throw new EngineException(engineMessage ?? $"Unknown engine excepiton in {callerName}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -319,7 +319,7 @@ internal static unsafe partial class ScriptGlue
|
|||||||
struct ComponentFunctionPointers
|
struct ComponentFunctionPointers
|
||||||
{
|
{
|
||||||
public delegate* unmanaged[Cdecl]<UUID, void> AddComponent;
|
public delegate* unmanaged[Cdecl]<UUID, void> AddComponent;
|
||||||
public delegate* unmanaged[Cdecl]<UUID, bool> HasComponent;
|
public delegate* unmanaged[Cdecl]<UUID, EngineResult> HasComponent;
|
||||||
public delegate* unmanaged[Cdecl]<UUID, void> RemoveComponent;
|
public delegate* unmanaged[Cdecl]<UUID, void> RemoveComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,7 +328,7 @@ internal static unsafe partial class ScriptGlue
|
|||||||
[UnmanagedCallersOnly]
|
[UnmanagedCallersOnly]
|
||||||
public static void RegisterComponentType(byte* fullComponentTypeName,
|
public static void RegisterComponentType(byte* fullComponentTypeName,
|
||||||
delegate* unmanaged[Cdecl]<UUID, void> addComponent,
|
delegate* unmanaged[Cdecl]<UUID, void> addComponent,
|
||||||
delegate* unmanaged[Cdecl]<UUID, bool> hasComponent,
|
delegate* unmanaged[Cdecl]<UUID, EngineResult> hasComponent,
|
||||||
delegate* unmanaged[Cdecl]<UUID, void> removeComponent)
|
delegate* unmanaged[Cdecl]<UUID, void> removeComponent)
|
||||||
{
|
{
|
||||||
string? beefComponentTypeName = Marshal.PtrToStringUTF8((IntPtr)fullComponentTypeName);
|
string? beefComponentTypeName = Marshal.PtrToStringUTF8((IntPtr)fullComponentTypeName);
|
||||||
@@ -421,7 +421,9 @@ internal static unsafe partial class ScriptGlue
|
|||||||
|
|
||||||
public static bool Entity_HasComponent(UUID entityId, Type componentType)
|
public static bool Entity_HasComponent(UUID entityId, Type componentType)
|
||||||
{
|
{
|
||||||
return ComponentTypeFunctions[componentType].HasComponent(entityId);
|
EngineResult returnValue = ComponentTypeFunctions[componentType].HasComponent(entityId);
|
||||||
|
EngineErrors.ThrowIfError(returnValue);
|
||||||
|
return returnValue == EngineResult.Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Entity_RemoveComponent(UUID entityId, Type componentType)
|
public static void Entity_RemoveComponent(UUID entityId, Type componentType)
|
||||||
|
|||||||
Reference in New Issue
Block a user