mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
499ca0311c | ||
|
|
62c85e9e1f | ||
|
|
8296f1c5cd |
+4
-1
@@ -30,4 +30,7 @@
|
|||||||
url = https://github.com/jazzbre/box2d-beef.git
|
url = https://github.com/jazzbre/box2d-beef.git
|
||||||
[submodule "GlitchyEngine/vendor/Beef.Linq"]
|
[submodule "GlitchyEngine/vendor/Beef.Linq"]
|
||||||
path = GlitchyEngine/vendor/Beef.Linq
|
path = GlitchyEngine/vendor/Beef.Linq
|
||||||
url = https://github.com/aharabada/Beef.Linq.git
|
url = https://github.com/aharabada/Beef.Linq.git
|
||||||
|
[submodule "GlitchyEngine/vendor/NetHostBeef"]
|
||||||
|
path = GlitchyEngine/vendor/NetHostBeef
|
||||||
|
url = https://github.com/aharabada/NetHostBeef.git
|
||||||
|
|||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
FileVersion = 1
|
FileVersion = 1
|
||||||
Projects = {Sandbox = {Path = "Sandbox"}, GlitchyEngine = {Path = "GlitchyEngine"}, GlitchLog = {Path = "GlitchLog"}, DirectX = {Path = "GlitchyEngine/vendor/directx/DirectX"}, LodePng = {Path = "vendor/lodepng-beef/lodepng-beef"}, FreeType = {Path = "GlitchyEngine/vendor/freetype"}, cgltf-beef = {Path = "GlitchyEngine/vendor/gltf/cgltf-beef"}, GlitchyEditor = {Path = "GlitchyEditor"}, msdfgen-beef = {Path = "GlitchyEngine/vendor/msdfgen/msdfgen-beef"}, ImGui = {Path = "GlitchyEngine/vendor/imgui/ImGui"}, ImGuiImplDX11 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplDX11"}, ImGuiImplWin32 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplWin32"}, ImGuizmo = {Path = "GlitchyEngine/vendor/imgui/ImGuizmo"}, GlitchyEngineHelper = {Path = "GlitchyEngineHelper"}, bon = {Path = "GlitchyEngine/vendor/bon"}, box2d-beef = {Path = "GlitchyEngine/vendor/box2D"}, "Beef.Linq" = {Path = "GlitchyEngine/vendor/Beef.Linq/src"}, ScriptCore = {Path = "ScriptCore"}}
|
Projects = {Sandbox = {Path = "Sandbox"}, GlitchyEngine = {Path = "GlitchyEngine"}, GlitchLog = {Path = "GlitchLog"}, DirectX = {Path = "GlitchyEngine/vendor/directx/DirectX"}, LodePng = {Path = "vendor/lodepng-beef/lodepng-beef"}, FreeType = {Path = "GlitchyEngine/vendor/freetype"}, cgltf-beef = {Path = "GlitchyEngine/vendor/gltf/cgltf-beef"}, GlitchyEditor = {Path = "GlitchyEditor"}, msdfgen-beef = {Path = "GlitchyEngine/vendor/msdfgen/msdfgen-beef"}, ImGui = {Path = "GlitchyEngine/vendor/imgui/ImGui"}, ImGuiImplDX11 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplDX11"}, ImGuiImplWin32 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplWin32"}, ImGuizmo = {Path = "GlitchyEngine/vendor/imgui/ImGuizmo"}, GlitchyEngineHelper = {Path = "GlitchyEngineHelper"}, bon = {Path = "GlitchyEngine/vendor/bon"}, box2d-beef = {Path = "GlitchyEngine/vendor/box2D"}, "Beef.Linq" = {Path = "GlitchyEngine/vendor/Beef.Linq/src"}, ScriptCore = {Path = "ScriptCore"}, NetHostBeef = {Path = "GlitchyEngine/vendor/NetHostBeef/NetHostBeef"}}
|
||||||
Unlocked = ["corlib"]
|
Unlocked = ["corlib"]
|
||||||
WorkspaceFolders = {GlitchyEngine = ["GlitchyEngine", "GlitchLog", "GlitchyEngineHelper", "ScriptCore"], "GlitchyEngine/Dependencies" = ["cgltf-beef", "DirectX", "FreeType", "ImGui", "ImGuiImplDX11", "ImGuiImplWin32", "ImGuizmo", "LodePng", "msdfgen-beef", "bon", "box2d-beef", "Beef.Linq"]}
|
WorkspaceFolders = {GlitchyEngine = ["GlitchyEngine", "GlitchLog", "GlitchyEngineHelper", "ScriptCore"], "GlitchyEngine/Dependencies" = ["cgltf-beef", "DirectX", "FreeType", "ImGui", "ImGuiImplDX11", "ImGuiImplWin32", "ImGuizmo", "LodePng", "msdfgen-beef", "bon", "box2d-beef", "Beef.Linq", "NetHostBeef"]}
|
||||||
|
|
||||||
[Workspace]
|
[Workspace]
|
||||||
StartupProject = "GlitchyEditor"
|
StartupProject = "GlitchyEditor"
|
||||||
|
|||||||
@@ -15,32 +15,39 @@ public class Camera : Entity
|
|||||||
|
|
||||||
public float DontFollowRadius = 3.0f;
|
public float DontFollowRadius = 3.0f;
|
||||||
|
|
||||||
void OnUpdate(float deltaTime)
|
void OnCreate()
|
||||||
{
|
{
|
||||||
Entity player = FindEntityWithName("Player");
|
Log.Info("Camera Create");
|
||||||
|
}
|
||||||
|
|
||||||
if (player != null)
|
public void OnUpdate(float deltaTime)
|
||||||
{
|
{
|
||||||
float2 playerPosition = player.Transform.Translation.XY;
|
Log.Info($"Camera Update {deltaTime}");
|
||||||
|
|
||||||
float2 cameraPosition = Transform.Translation.XY;
|
//Entity player = FindEntityWithName("Player");
|
||||||
|
|
||||||
float2 distanceVector = playerPosition - cameraPosition;
|
//if (player != null)
|
||||||
|
//{
|
||||||
|
// float2 playerPosition = player.Transform.Translation.XY;
|
||||||
|
|
||||||
float distance = length(distanceVector);
|
// float2 cameraPosition = Transform.Translation.XY;
|
||||||
|
|
||||||
float2 neededMovement = float2.Zero;
|
// float2 distanceVector = playerPosition - cameraPosition;
|
||||||
|
|
||||||
if (distance > DontFollowRadius)
|
// float distance = length(distanceVector);
|
||||||
{
|
|
||||||
neededMovement = distanceVector - (distanceVector / distance) * DontFollowRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
Transform.Translation = new float3(cameraPosition + neededMovement, DistanceFromPlayer);
|
// float2 neededMovement = float2.Zero;
|
||||||
}
|
|
||||||
else
|
// if (distance > DontFollowRadius)
|
||||||
{
|
// {
|
||||||
Log.Error("Player not found!");
|
// neededMovement = distanceVector - (distanceVector / distance) * DontFollowRadius;
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
// Transform.Translation = new float3(cameraPosition + neededMovement, DistanceFromPlayer);
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// Log.Error("Player not found!");
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.Remoting.Metadata.W3cXsd2001;
|
|
||||||
using GlitchyEngine;
|
using GlitchyEngine;
|
||||||
using GlitchyEngine.Editor;
|
using GlitchyEngine.Editor;
|
||||||
using GlitchyEngine.Math;
|
using GlitchyEngine.Math;
|
||||||
@@ -11,9 +10,9 @@ namespace Sandbox
|
|||||||
|
|
||||||
public enum MyEnum
|
public enum MyEnum
|
||||||
{
|
{
|
||||||
Yes = 1,
|
Yes,
|
||||||
No,
|
No,
|
||||||
Maybe = 1337
|
Maybe
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct MyStruct
|
public struct MyStruct
|
||||||
@@ -25,38 +24,36 @@ namespace Sandbox
|
|||||||
|
|
||||||
class MyTestEntity : Entity
|
class MyTestEntity : Entity
|
||||||
{
|
{
|
||||||
[ShowInEditor]
|
//[ShowInEditor]
|
||||||
RigidBody2D _rigidBody;
|
RigidBody2D _rigidBody;
|
||||||
|
|
||||||
//public bool Bo;
|
public bool Bo;
|
||||||
|
|
||||||
//public byte By;
|
public byte By;
|
||||||
//public ushort Us;
|
public ushort Us;
|
||||||
//public uint Ui;
|
public uint Ui;
|
||||||
//public ulong Ul;
|
public ulong Ul;
|
||||||
|
|
||||||
//public sbyte Sb;
|
public sbyte Sb;
|
||||||
//public short Sh;
|
public short Sh;
|
||||||
//public int In;
|
public int In;
|
||||||
//public long Lo;
|
public long Lo;
|
||||||
|
|
||||||
//public float Fl;
|
public float Fl;
|
||||||
//public double Do;
|
public double Do;
|
||||||
//public float2 V2;
|
public float2 V2;
|
||||||
//public float3 V3;
|
public float3 V3;
|
||||||
//public float4 V4;
|
public float4 V4;
|
||||||
|
|
||||||
public Entity TheEntity;
|
public Entity TheEntity;
|
||||||
|
|
||||||
public float JumpForce = 2000;
|
public float JumpForce = 2000;
|
||||||
[ShowInEditor] float MoveForce = 1000;
|
[ShowInEditor] float MoveForce = 1000;
|
||||||
[ShowInEditor] private int MyNumber = 1337;
|
[ShowInEditor] private int MyNumber = 1337;
|
||||||
//[ShowInEditor] public double MyDouble = 1000.0f;
|
[ShowInEditor] public double MyDouble = 1000.0f;
|
||||||
|
|
||||||
public MyStruct AStruct;
|
public MyStruct AStruct;
|
||||||
|
|
||||||
public MyEnum AEnum = MyEnum.Maybe;
|
|
||||||
|
|
||||||
public Camera Camera;
|
public Camera Camera;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -70,37 +67,12 @@ namespace Sandbox
|
|||||||
|
|
||||||
//_rigidBody ??= GetComponent<RigidBody2D>() ?? AddComponent<RigidBody2D>();
|
//_rigidBody ??= GetComponent<RigidBody2D>() ?? AddComponent<RigidBody2D>();
|
||||||
|
|
||||||
if (_rigidBody == null)
|
//Camera = FindEntityWithName("Camera").As<Camera>();
|
||||||
{
|
|
||||||
Log.Error("_rigidBody was not set in editor.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Camera == null)
|
//if (Camera == null)
|
||||||
{
|
//{
|
||||||
Log.Warning("Camera wasn't set in editor. Searching...");
|
// Log.Error("Camera not found.");
|
||||||
Camera = FindEntityWithName("Camera").As<Camera>();
|
//}
|
||||||
|
|
||||||
if (Camera == null)
|
|
||||||
{
|
|
||||||
Log.Error("Camera not found.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Log.Warning("Achtung.");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
SubVoid();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Console.WriteLine(e);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SubVoid()
|
|
||||||
{
|
|
||||||
throw new Exception("Ouha!", new IndexOutOfRangeException("Bist du jecke2?!", new AccessViolationException("Haleluja")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -109,39 +81,38 @@ namespace Sandbox
|
|||||||
/// <param name="deltaTime"></param>
|
/// <param name="deltaTime"></param>
|
||||||
void OnUpdate(float deltaTime)
|
void OnUpdate(float deltaTime)
|
||||||
{
|
{
|
||||||
float2 force = float2.Zero;
|
Log.Info($"On update: {deltaTime}");
|
||||||
|
|
||||||
if (Input.IsKeyPressed(Key.A))
|
//float2 force = float2.Zero;
|
||||||
{
|
|
||||||
force.X -= MoveForce * deltaTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Input.IsKeyPressed(Key.D))
|
//if (Input.IsKeyPressed(Key.A))
|
||||||
{
|
//{
|
||||||
force.X += MoveForce * deltaTime;
|
// force.X -= MoveForce * deltaTime;
|
||||||
}
|
//}
|
||||||
|
|
||||||
if (Input.IsKeyPressed(Key.Q))
|
//if (Input.IsKeyPressed(Key.D))
|
||||||
Camera.DistanceFromPlayer -= deltaTime;
|
//{
|
||||||
|
// force.X += MoveForce * deltaTime;
|
||||||
|
//}
|
||||||
|
|
||||||
if (Input.IsKeyPressed(Key.E))
|
//if (Input.IsKeyPressed(Key.Q))
|
||||||
Camera.DistanceFromPlayer += deltaTime;
|
// Camera.DistanceFromPlayer -= deltaTime;
|
||||||
|
|
||||||
if (Input.IsKeyPressing(Key.Space))
|
|
||||||
{
|
|
||||||
force.Y += JumpForce;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Input.IsKeyPressing(Key.N))
|
|
||||||
SubVoid();
|
|
||||||
|
|
||||||
_rigidBody.ApplyForceToCenter(force);
|
//if (Input.IsKeyPressed(Key.E))
|
||||||
|
// Camera.DistanceFromPlayer += deltaTime;
|
||||||
|
|
||||||
if (Input.IsMouseButtonReleasing(MouseButton.MiddleButton))
|
//if (Input.IsKeyPressing(Key.Space))
|
||||||
{
|
//{
|
||||||
Log.Info($"Ouha! {MyNumber}");
|
// force.Y += JumpForce;
|
||||||
Physics2D.Gravity *= new float2(1, -1);
|
//}
|
||||||
}
|
|
||||||
|
//_rigidBody.ApplyForceToCenter(force);
|
||||||
|
|
||||||
|
//if (Input.IsMouseButtonReleasing(MouseButton.MiddleButton))
|
||||||
|
//{
|
||||||
|
// Log.Info($"Ouha! {MyNumber}");
|
||||||
|
// Physics2D.Gravity *= new float2(1, -1);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
using System.Reflection;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
// Allgemeine Informationen über eine Assembly werden über die folgenden
|
|
||||||
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
|
||||||
// die einer Assembly zugeordnet sind.
|
|
||||||
[assembly: AssemblyTitle("Sanbox")]
|
|
||||||
[assembly: AssemblyDescription("")]
|
|
||||||
[assembly: AssemblyConfiguration("")]
|
|
||||||
[assembly: AssemblyCompany("")]
|
|
||||||
[assembly: AssemblyProduct("Sanbox")]
|
|
||||||
[assembly: AssemblyCopyright("Copyright © 2023")]
|
|
||||||
[assembly: AssemblyTrademark("")]
|
|
||||||
[assembly: AssemblyCulture("")]
|
|
||||||
|
|
||||||
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
|
|
||||||
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
|
|
||||||
// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
|
|
||||||
[assembly: ComVisible(false)]
|
|
||||||
|
|
||||||
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
|
|
||||||
[assembly: Guid("7a70819c-5317-402a-8553-95c5a001e370")]
|
|
||||||
|
|
||||||
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
|
||||||
//
|
|
||||||
// Hauptversion
|
|
||||||
// Nebenversion
|
|
||||||
// Buildnummer
|
|
||||||
// Revision
|
|
||||||
//
|
|
||||||
// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
|
|
||||||
// indem Sie "*" wie unten gezeigt eingeben:
|
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
|
||||||
[assembly: AssemblyVersion("1.0.0.0")]
|
|
||||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"profiles": {
|
||||||
|
"Start Editor": {
|
||||||
|
"commandName": "Executable",
|
||||||
|
"executablePath": "D:\\Development\\Projects\\Beef\\GlitchyEngine\\build\\Debug_Win64\\GlitchyEditor\\GlitchyEditor.exe",
|
||||||
|
"commandLineArgs": "\"content\\Scenes\\physics2D.scene\"",
|
||||||
|
"workingDirectory": "D:\\Development\\Projects\\Beef\\GlitchyEngine\\GlitchyEditor",
|
||||||
|
"nativeDebugging": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{7A70819C-5317-402A-8553-95C5A001E370}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>Sandbox</RootNamespace>
|
||||||
|
<AssemblyName>Sandbox</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<Deterministic>true</Deterministic>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<LangVersion>default</LangVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<LangVersion>default</LangVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Camera.cs" />
|
||||||
|
<Compile Include="MyTestEntity.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\..\ScriptCore\ScriptCore.csproj">
|
||||||
|
<Project>{6222c226-fc78-498c-80ba-5cf10ac9123c}</Project>
|
||||||
|
<Name>ScriptCore</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
||||||
@@ -1,57 +1,16 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
<LangVersion>latest</LangVersion>
|
||||||
<ProjectGuid>{7A70819C-5317-402A-8553-95C5A001E370}</ProjectGuid>
|
<OutputPath>bin</OutputPath>
|
||||||
<OutputType>Library</OutputType>
|
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
|
||||||
<RootNamespace>Sandbox</RootNamespace>
|
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||||
<AssemblyName>Sandbox</AssemblyName>
|
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||||
<FileAlignment>512</FileAlignment>
|
|
||||||
<Deterministic>true</Deterministic>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
|
||||||
<DebugType>portable</DebugType>
|
|
||||||
<Optimize>false</Optimize>
|
|
||||||
<OutputPath>bin\</OutputPath>
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
<LangVersion>default</LangVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
|
||||||
<DebugType>pdbonly</DebugType>
|
|
||||||
<Optimize>true</Optimize>
|
|
||||||
<OutputPath>bin\</OutputPath>
|
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
<LangVersion>default</LangVersion>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System" />
|
<ProjectReference Include="..\..\..\..\ScriptCore\ScriptCore.csproj" />
|
||||||
<Reference Include="System.Core" />
|
|
||||||
<Reference Include="System.Xml.Linq" />
|
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
|
||||||
<Reference Include="Microsoft.CSharp" />
|
|
||||||
<Reference Include="System.Data" />
|
|
||||||
<Reference Include="System.Net.Http" />
|
|
||||||
<Reference Include="System.Xml" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<Compile Include="Camera.cs" />
|
</Project>
|
||||||
<Compile Include="MyTestEntity.cs" />
|
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\..\..\ScriptCore\ScriptCore.csproj">
|
|
||||||
<Project>{6222c226-fc78-498c-80ba-5cf10ac9123c}</Project>
|
|
||||||
<Name>ScriptCore</Name>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
|
||||||
</Project>
|
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using GlitchyEngine;
|
||||||
|
|
||||||
|
namespace Sandbox;
|
||||||
|
|
||||||
|
public static class TestClass
|
||||||
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static void TestFunction()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Hello from the second Assembly!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void InternalTest()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Ja, ich existiere in der Tat");
|
||||||
|
|
||||||
|
Log.Info("Yeah!");
|
||||||
|
//Console.WriteLine("Und nun bin ich anders");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int Test(IntPtr arg, int sizeofArg)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"YUPPYPLASDPASDOIUZASD");
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -71,8 +71,8 @@
|
|||||||
SpriteRendererComponent = {
|
SpriteRendererComponent = {
|
||||||
Color = {
|
Color = {
|
||||||
R = 1,
|
R = 1,
|
||||||
G = 0.941887021,
|
G = 0.941886961,
|
||||||
B = 0.401484489,
|
B = 0.401484549,
|
||||||
A = 1
|
A = 1
|
||||||
},
|
},
|
||||||
Sprite = "",
|
Sprite = "",
|
||||||
@@ -162,7 +162,7 @@
|
|||||||
OrthographicHeight = 10,
|
OrthographicHeight = 10,
|
||||||
OrthographicNearPlane = 0,
|
OrthographicNearPlane = 0,
|
||||||
OrthographicFarPlane = 10,
|
OrthographicFarPlane = 10,
|
||||||
AspectRatio = 2.05582929,
|
AspectRatio = 0.884925187,
|
||||||
FixedAspectRatio = false
|
FixedAspectRatio = false
|
||||||
},
|
},
|
||||||
ScriptComponent = {
|
ScriptComponent = {
|
||||||
@@ -195,8 +195,8 @@
|
|||||||
},
|
},
|
||||||
TransformComponent = {
|
TransformComponent = {
|
||||||
Position = {
|
Position = {
|
||||||
X = -0.121203206,
|
X = -0.121203184,
|
||||||
Y = 0.660161078,
|
Y = 0.660160959,
|
||||||
Z = 0
|
Z = 0
|
||||||
},
|
},
|
||||||
Rotation = {
|
Rotation = {
|
||||||
@@ -234,12 +234,37 @@
|
|||||||
ScriptComponent = {
|
ScriptComponent = {
|
||||||
ScriptClass = "Sandbox.MyTestEntity",
|
ScriptClass = "Sandbox.MyTestEntity",
|
||||||
Fields = [
|
Fields = [
|
||||||
_rigidBody = (Component)15710354273720487680,
|
Bo = (Bool)false,
|
||||||
|
By = (Byte)0,
|
||||||
|
Us = (UShort)57,
|
||||||
|
Ui = (UInt)54,
|
||||||
|
Ul = (ULong)53,
|
||||||
|
Sb = (SByte)-128,
|
||||||
|
Sh = (Short)95,
|
||||||
|
In = (Int)-149,
|
||||||
|
Lo = (Long)82,
|
||||||
|
Fl = (Float)-98.122963,
|
||||||
|
Do = (Double)118,
|
||||||
|
V2 = (float2){
|
||||||
|
X = 11,
|
||||||
|
Y = 12
|
||||||
|
},
|
||||||
|
V3 = (float3){
|
||||||
|
X = 13,
|
||||||
|
Y = 14,
|
||||||
|
Z = 15
|
||||||
|
},
|
||||||
|
V4 = (float4){
|
||||||
|
X = 14,
|
||||||
|
Y = 17,
|
||||||
|
Z = 18,
|
||||||
|
W = 19
|
||||||
|
},
|
||||||
TheEntity = (Entity)0,
|
TheEntity = (Entity)0,
|
||||||
JumpForce = (Float)200,
|
JumpForce = (Float)200,
|
||||||
MoveForce = (Float)148,
|
MoveForce = (Float)148,
|
||||||
MyNumber = (Int)22,
|
MyNumber = (Int)22,
|
||||||
Camera = (Entity)1491484622542812645
|
MyDouble = (Double)23
|
||||||
] }
|
] }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -276,7 +301,7 @@
|
|||||||
Color = {
|
Color = {
|
||||||
R = 0.985467017,
|
R = 0.985467017,
|
||||||
G = 1,
|
G = 1,
|
||||||
B = 0.569977939
|
B = 0.569978058
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -323,8 +348,8 @@
|
|||||||
SpriteRendererComponent = {
|
SpriteRendererComponent = {
|
||||||
Color = {
|
Color = {
|
||||||
R = 0.425658971,
|
R = 0.425658971,
|
||||||
G = 0.855207443,
|
G = 0.855207562,
|
||||||
B = 0.0558161177,
|
B = 0.0558161102,
|
||||||
A = 1
|
A = 1
|
||||||
},
|
},
|
||||||
Sprite = "",
|
Sprite = "",
|
||||||
@@ -338,14 +363,14 @@
|
|||||||
TransformComponent = {
|
TransformComponent = {
|
||||||
Position = {
|
Position = {
|
||||||
X = 6.74610233,
|
X = 6.74610233,
|
||||||
Y = -2.03225946,
|
Y = -2.03225899,
|
||||||
Z = 0
|
Z = 0
|
||||||
},
|
},
|
||||||
Rotation = {
|
Rotation = {
|
||||||
X = 0,
|
X = 0,
|
||||||
Y = 0,
|
Y = 0,
|
||||||
Z = -0.331792623,
|
Z = -0.331792623,
|
||||||
W = 0.94335258
|
W = 0.943352342
|
||||||
},
|
},
|
||||||
Scale = {
|
Scale = {
|
||||||
X = 5.29557419,
|
X = 5.29557419,
|
||||||
@@ -384,7 +409,7 @@
|
|||||||
},
|
},
|
||||||
SpriteRendererComponent = {
|
SpriteRendererComponent = {
|
||||||
Color = {
|
Color = {
|
||||||
R = 0.666117013,
|
R = 0.666116953,
|
||||||
G = 0.0600316115,
|
G = 0.0600316115,
|
||||||
B = 1,
|
B = 1,
|
||||||
A = 1
|
A = 1
|
||||||
@@ -399,8 +424,8 @@
|
|||||||
},
|
},
|
||||||
TransformComponent = {
|
TransformComponent = {
|
||||||
Position = {
|
Position = {
|
||||||
X = 15.2321281,
|
X = 15.2321301,
|
||||||
Y = -1.98709273,
|
Y = -1.98709249,
|
||||||
Z = 0
|
Z = 0
|
||||||
},
|
},
|
||||||
Rotation = {
|
Rotation = {
|
||||||
@@ -410,7 +435,7 @@
|
|||||||
W = 0.990847468
|
W = 0.990847468
|
||||||
},
|
},
|
||||||
Scale = {
|
Scale = {
|
||||||
X = 13.9764528,
|
X = 13.9764566,
|
||||||
Y = 1,
|
Y = 1,
|
||||||
Z = 1
|
Z = 1
|
||||||
},
|
},
|
||||||
@@ -446,7 +471,7 @@
|
|||||||
},
|
},
|
||||||
SpriteRendererComponent = {
|
SpriteRendererComponent = {
|
||||||
Color = {
|
Color = {
|
||||||
R = 0.176544309,
|
R = 0.176544324,
|
||||||
G = 0.666713238,
|
G = 0.666713238,
|
||||||
B = 0.687030852,
|
B = 0.687030852,
|
||||||
A = 1
|
A = 1
|
||||||
@@ -462,24 +487,24 @@
|
|||||||
TransformComponent = {
|
TransformComponent = {
|
||||||
Position = {
|
Position = {
|
||||||
X = -6.27842855,
|
X = -6.27842855,
|
||||||
Y = 2.62550163,
|
Y = 2.62550211,
|
||||||
Z = 0
|
Z = 0
|
||||||
},
|
},
|
||||||
Rotation = {
|
Rotation = {
|
||||||
X = 0,
|
X = 0,
|
||||||
Y = 0,
|
Y = 0,
|
||||||
Z = 0.187087879,
|
Z = 0.187087834,
|
||||||
W = 0.982343197
|
W = 0.982343197
|
||||||
},
|
},
|
||||||
Scale = {
|
Scale = {
|
||||||
X = 0.999999464,
|
X = 0.999999523,
|
||||||
Y = 6.49634314,
|
Y = 6.49634314,
|
||||||
Z = 1
|
Z = 1
|
||||||
},
|
},
|
||||||
EditorEulerRotation = {
|
EditorEulerRotation = {
|
||||||
X = 0,
|
X = 0,
|
||||||
Y = 0,
|
Y = 0,
|
||||||
Z = 0.376393616
|
Z = 0.376393586
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Rigidbody2D = {
|
Rigidbody2D = {
|
||||||
@@ -497,7 +522,7 @@
|
|||||||
},
|
},
|
||||||
Density = 1,
|
Density = 1,
|
||||||
Friction = 0.5,
|
Friction = 0.5,
|
||||||
Restitution = 0.899999857,
|
Restitution = 0.899999976,
|
||||||
RestitutionThreshold = 0.5
|
RestitutionThreshold = 0.5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -9,8 +9,8 @@
|
|||||||
AddressModeU = .Clamp,
|
AddressModeU = .Clamp,
|
||||||
AddressModeV = .Clamp,
|
AddressModeV = .Clamp,
|
||||||
AddressModeW = .Clamp,
|
AddressModeW = .Clamp,
|
||||||
MipMinLOD = -3.40282347e+38,
|
MipMinLOD = -340282346638528859811704183484516925440,
|
||||||
MipMaxLOD = 3.40282347e+38,
|
MipMaxLOD = 340282346638528859811704183484516925440,
|
||||||
MaxAnisotropy = 1,
|
MaxAnisotropy = 1,
|
||||||
BorderColor = {
|
BorderColor = {
|
||||||
R = 1,
|
R = 1,
|
||||||
|
|||||||
Binary file not shown.
@@ -1,34 +1,15 @@
|
|||||||
{
|
{
|
||||||
"runtimeTarget": {
|
"runtimeTarget": {
|
||||||
"name": ".NETStandard,Version=v2.0/",
|
"name": ".NETCoreApp,Version=v7.0",
|
||||||
"signature": ""
|
"signature": ""
|
||||||
},
|
},
|
||||||
"compilationOptions": {},
|
"compilationOptions": {},
|
||||||
"targets": {
|
"targets": {
|
||||||
".NETStandard,Version=v2.0": {},
|
".NETCoreApp,Version=v7.0": {
|
||||||
".NETStandard,Version=v2.0/": {
|
|
||||||
"ScriptCore/1.0.0": {
|
"ScriptCore/1.0.0": {
|
||||||
"dependencies": {
|
|
||||||
"Half": "1.0.0",
|
|
||||||
"NETStandard.Library": "2.0.3"
|
|
||||||
},
|
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"ScriptCore.dll": {}
|
"ScriptCore.dll": {}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"Half/1.0.0": {
|
|
||||||
"runtime": {
|
|
||||||
"lib/netstandard2.0/System.Half.dll": {
|
|
||||||
"assemblyVersion": "1.0.0.0",
|
|
||||||
"fileVersion": "1.0.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Microsoft.NETCore.Platforms/1.1.0": {},
|
|
||||||
"NETStandard.Library/2.0.3": {
|
|
||||||
"dependencies": {
|
|
||||||
"Microsoft.NETCore.Platforms": "1.1.0"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -37,27 +18,6 @@
|
|||||||
"type": "project",
|
"type": "project",
|
||||||
"serviceable": false,
|
"serviceable": false,
|
||||||
"sha512": ""
|
"sha512": ""
|
||||||
},
|
|
||||||
"Half/1.0.0": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-EPLLPQA1UjF9QM3ymNhWLhgcnBNc8e1po4qWRWTD3Hd9xiohYlkCob0QjDIbJs6Nvfd4eAbsjxIwRyh7httyXA==",
|
|
||||||
"path": "half/1.0.0",
|
|
||||||
"hashPath": "half.1.0.0.nupkg.sha512"
|
|
||||||
},
|
|
||||||
"Microsoft.NETCore.Platforms/1.1.0": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==",
|
|
||||||
"path": "microsoft.netcore.platforms/1.1.0",
|
|
||||||
"hashPath": "microsoft.netcore.platforms.1.1.0.nupkg.sha512"
|
|
||||||
},
|
|
||||||
"NETStandard.Library/2.0.3": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
|
|
||||||
"path": "netstandard.library/2.0.3",
|
|
||||||
"hashPath": "netstandard.library.2.0.3.nupkg.sha512"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"runtimeOptions": {
|
||||||
|
"additionalProbingPaths": [
|
||||||
|
"C:\\Users\\Simon\\.dotnet\\store\\|arch|\\|tfm|",
|
||||||
|
"C:\\Users\\Simon\\.nuget\\packages",
|
||||||
|
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"runtimeOptions": {
|
||||||
|
"tfm": "net7.0",
|
||||||
|
"rollForward": "LatestMinor",
|
||||||
|
"framework": {
|
||||||
|
"name": "Microsoft.NETCore.App",
|
||||||
|
"version": "7.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
|||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
if (ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
||||||
|
|
||||||
if (payload != null)
|
if (payload != null)
|
||||||
{
|
{
|
||||||
@@ -78,7 +78,7 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
|||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
if (ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
||||||
|
|
||||||
if (payload != null)
|
if (payload != null)
|
||||||
{
|
{
|
||||||
@@ -120,7 +120,7 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
|||||||
|
|
||||||
value = (float3)ColorRGB.LinearToSRGB((ColorRGB)value);
|
value = (float3)ColorRGB.LinearToSRGB((ColorRGB)value);
|
||||||
|
|
||||||
if (ImGui.ColorEdit3(displayName.Ptr, ref *(float[3]*)&value))
|
if (ImGui.ColorEdit3(displayName.Ptr, *(float[3]*)&value))
|
||||||
{
|
{
|
||||||
value = (float3)ColorRGB.SRgbToLinear((ColorRGB)value);
|
value = (float3)ColorRGB.SRgbToLinear((ColorRGB)value);
|
||||||
material.SetVariable(variable.Name, value);
|
material.SetVariable(variable.Name, value);
|
||||||
@@ -132,7 +132,7 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
|||||||
|
|
||||||
value = (float4)ColorRGBA.LinearToSRGB((ColorRGBA)value);
|
value = (float4)ColorRGBA.LinearToSRGB((ColorRGBA)value);
|
||||||
|
|
||||||
if (ImGui.ColorEdit4(displayName.Ptr, ref *(float[4]*)&value))
|
if (ImGui.ColorEdit4(displayName.Ptr, *(float[4]*)&value))
|
||||||
{
|
{
|
||||||
value = (float4)ColorRGBA.SRgbToLinear((ColorRGBA)value);
|
value = (float4)ColorRGBA.SRgbToLinear((ColorRGBA)value);
|
||||||
material.SetVariable(variable.Name, value);
|
material.SetVariable(variable.Name, value);
|
||||||
@@ -149,7 +149,7 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
|||||||
|
|
||||||
value = (float3)ColorRGB.LinearToSRGB((ColorRGB)value);
|
value = (float3)ColorRGB.LinearToSRGB((ColorRGB)value);
|
||||||
|
|
||||||
if (ImGui.ColorEdit3(displayName.Ptr, ref *(float[3]*)&value, .HDR | .Float))
|
if (ImGui.ColorEdit3(displayName.Ptr, *(float[3]*)&value, .HDR | .Float))
|
||||||
{
|
{
|
||||||
value = (float3)ColorRGB.SRgbToLinear((ColorRGB)value);
|
value = (float3)ColorRGB.SRgbToLinear((ColorRGB)value);
|
||||||
material.SetVariable(variable.Name, value);
|
material.SetVariable(variable.Name, value);
|
||||||
@@ -161,7 +161,7 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
|||||||
|
|
||||||
value = (float4)ColorRGBA.LinearToSRGB((ColorRGBA)value);
|
value = (float4)ColorRGBA.LinearToSRGB((ColorRGBA)value);
|
||||||
|
|
||||||
if (ImGui.ColorEdit4(displayName.Ptr, ref *(float[4]*)&value, .HDR | .Float))
|
if (ImGui.ColorEdit4(displayName.Ptr, *(float[4]*)&value, .HDR | .Float))
|
||||||
{
|
{
|
||||||
value = (float4)ColorRGBA.SRgbToLinear((ColorRGBA)value);
|
value = (float4)ColorRGBA.SRgbToLinear((ColorRGBA)value);
|
||||||
material.SetVariable(variable.Name, value);
|
material.SetVariable(variable.Name, value);
|
||||||
|
|||||||
@@ -31,58 +31,7 @@ class AssetViewer : EditorWindow
|
|||||||
|
|
||||||
ImGui.PushStyleVar(.CellPadding, .(0, 0));
|
ImGui.PushStyleVar(.CellPadding, .(0, 0));
|
||||||
|
|
||||||
ImGui.Columns(2);
|
bool alt_pressed = ImGui.GetIO().KeyAlt;
|
||||||
|
|
||||||
if (ImGui.BeginChild("Assets"))
|
|
||||||
{
|
|
||||||
DrawAssetList();
|
|
||||||
|
|
||||||
ImGui.EndChild();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.NextColumn();
|
|
||||||
|
|
||||||
if (ImGui.BeginChild("Files"))
|
|
||||||
{
|
|
||||||
DrawAssetViewer();
|
|
||||||
|
|
||||||
ImGui.EndChild();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.Columns(1);
|
|
||||||
|
|
||||||
/*if (ImGui.BeginTable("AssetViewerTable", 2, .BordersInnerV | .Resizable | .Reorderable | .NoPadOuterX))
|
|
||||||
{
|
|
||||||
if (alt_pressed)
|
|
||||||
{
|
|
||||||
// Header anzeigen, damit sie neu angeordnet werden können
|
|
||||||
ImGui.TableSetupColumn("Assets");
|
|
||||||
ImGui.TableSetupColumn("Viewer");
|
|
||||||
ImGui.TableHeadersRow();
|
|
||||||
}
|
|
||||||
ImGui.TableNextRow();
|
|
||||||
ImGui.TableSetColumnIndex(0);
|
|
||||||
|
|
||||||
if (ImGui.BeginChild("Assets"))
|
|
||||||
{
|
|
||||||
//DrawAssetList();
|
|
||||||
|
|
||||||
ImGui.EndChild();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
|
|
||||||
if (ImGui.BeginChild("Files"))
|
|
||||||
{
|
|
||||||
//DrawAssetViewer();
|
|
||||||
|
|
||||||
ImGui.EndChild();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndTable();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/*bool alt_pressed = ImGui.GetIO().KeyAlt;
|
|
||||||
|
|
||||||
if (ImGui.BeginTable("AssetViewerTable", 2, .BordersInnerV | .Resizable | .Reorderable | .NoPadOuterX))
|
if (ImGui.BeginTable("AssetViewerTable", 2, .BordersInnerV | .Resizable | .Reorderable | .NoPadOuterX))
|
||||||
{
|
{
|
||||||
@@ -93,12 +42,13 @@ class AssetViewer : EditorWindow
|
|||||||
ImGui.TableSetupColumn("Viewer");
|
ImGui.TableSetupColumn("Viewer");
|
||||||
ImGui.TableHeadersRow();
|
ImGui.TableHeadersRow();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.TableNextRow();
|
ImGui.TableNextRow();
|
||||||
ImGui.TableSetColumnIndex(0);
|
ImGui.TableSetColumnIndex(0);
|
||||||
|
|
||||||
if (ImGui.BeginChild("Assets"))
|
if (ImGui.BeginChild("Assets"))
|
||||||
{
|
{
|
||||||
//DrawAssetList();
|
DrawAssetList();
|
||||||
|
|
||||||
ImGui.EndChild();
|
ImGui.EndChild();
|
||||||
}
|
}
|
||||||
@@ -107,13 +57,13 @@ class AssetViewer : EditorWindow
|
|||||||
|
|
||||||
if (ImGui.BeginChild("Files"))
|
if (ImGui.BeginChild("Files"))
|
||||||
{
|
{
|
||||||
//DrawAssetViewer();
|
DrawAssetViewer();
|
||||||
|
|
||||||
ImGui.EndChild();
|
ImGui.EndChild();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.EndTable();
|
ImGui.EndTable();
|
||||||
}*/
|
}
|
||||||
|
|
||||||
ImGui.PopStyleVar(1);
|
ImGui.PopStyleVar(1);
|
||||||
|
|
||||||
@@ -261,7 +211,7 @@ class TexturererViewerer
|
|||||||
|
|
||||||
float maxDimension = max(width, height);
|
float maxDimension = max(width, height);
|
||||||
|
|
||||||
ImGui.SliderFloat2("Position", ref *(float[2]*)&_position, 2 * -maxDimension * _zoom, 2 * maxDimension * _zoom);
|
ImGui.SliderFloat2("Position", *(float[2]*)&_position, 2 * -maxDimension * _zoom, 2 * maxDimension * _zoom);
|
||||||
|
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ using GlitchyEngine.Renderer;
|
|||||||
using GlitchyEngine;
|
using GlitchyEngine;
|
||||||
using GlitchyEngine.Content;
|
using GlitchyEngine.Content;
|
||||||
using GlitchyEngine.Scripting;
|
using GlitchyEngine.Scripting;
|
||||||
using GlitchyEngine.Core;
|
|
||||||
using Mono;
|
|
||||||
|
|
||||||
namespace GlitchyEditor.EditWindows
|
namespace GlitchyEditor.EditWindows
|
||||||
{
|
{
|
||||||
@@ -280,7 +278,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
if (ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
||||||
|
|
||||||
if (payload != null)
|
if (payload != null)
|
||||||
{
|
{
|
||||||
@@ -308,7 +306,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
if (ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
||||||
|
|
||||||
if (payload != null)
|
if (payload != null)
|
||||||
{
|
{
|
||||||
@@ -340,7 +338,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
if (ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
||||||
|
|
||||||
if (payload != null)
|
if (payload != null)
|
||||||
{
|
{
|
||||||
@@ -455,7 +453,8 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
StringView search = StringView();
|
StringView search = StringView();
|
||||||
|
|
||||||
char8* scriptLabel = scriptComponent.Instance?.ScriptClass.FullName.ToScopeCStr!() ?? "Select Script...";
|
//char8* scriptLabel = scriptComponent.Instance?.ScriptClass.FullName.ToScopeCStr!() ?? "Select Script...";
|
||||||
|
char8* scriptLabel = scriptComponent.Instance?.ScriptClass.FullName.CStr() ?? "Select Script...";
|
||||||
|
|
||||||
if (ImGui.Button(scriptLabel))
|
if (ImGui.Button(scriptLabel))
|
||||||
ImGui.OpenPopup("SelectScript");
|
ImGui.OpenPopup("SelectScript");
|
||||||
@@ -480,13 +479,15 @@ namespace GlitchyEditor.EditWindows
|
|||||||
//ScriptEngine.InitializeInstance(entity, scriptComponent);
|
//ScriptEngine.InitializeInstance(entity, scriptComponent);
|
||||||
|
|
||||||
scriptComponent.ScriptClassName = scriptClass.FullName;
|
scriptComponent.ScriptClassName = scriptClass.FullName;
|
||||||
|
|
||||||
ScriptEngine.CreateScriptFieldMap(entity);
|
//ScriptEngine.CreateScriptFieldMap(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui.EndPopup();
|
ImGui.EndPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
ScriptClass scriptClass = ScriptEngine.GetScriptClass(scriptComponent.ScriptClassName);
|
ScriptClass scriptClass = ScriptEngine.GetScriptClass(scriptComponent.ScriptClassName);
|
||||||
|
|
||||||
/*T GetFieldValue<T>()
|
/*T GetFieldValue<T>()
|
||||||
@@ -514,89 +515,11 @@ namespace GlitchyEditor.EditWindows
|
|||||||
scriptInstance.SetFieldValue<T>(scriptField, value);
|
scriptInstance.SetFieldValue<T>(scriptField, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
T GetData<T>(void* instance, ScriptField scriptField)
|
|
||||||
{
|
|
||||||
T data = default;
|
|
||||||
Mono.mono_field_get_value((.)instance, scriptField.[Friend]_monoField, &data);
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetData<T>(void* instance, ScriptField scriptField, T* data)
|
|
||||||
{
|
|
||||||
Mono.mono_field_get_value((.)instance, scriptField.[Friend]_monoField, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetData<T>(void* instance, ScriptField scriptField, in T value)
|
|
||||||
{
|
|
||||||
Mono.mono_field_set_value((.)instance, scriptField.[Friend]_monoField, &value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetData<T>(void* instance, ScriptField scriptField, T* data)
|
|
||||||
{
|
|
||||||
Mono.mono_field_set_value((.)instance, scriptField.[Friend]_monoField, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scriptComponent.Instance?.IsInitialized == true)
|
if (scriptComponent.Instance?.IsInitialized == true)
|
||||||
{
|
{
|
||||||
SharpClass sharpClass = scriptComponent.Instance.ScriptClass;
|
SharpClass sharpClass = scriptComponent.Instance.ScriptClass;
|
||||||
ScriptInstance scriptInstance = scriptComponent.Instance;
|
ScriptInstance scriptInstance = scriptComponent.Instance;
|
||||||
|
|
||||||
/*void DoFunnyStuff(void* instance, SharpType sharpType)
|
|
||||||
{
|
|
||||||
for (let (fieldName, scriptField) in sharpType.Fields)
|
|
||||||
{
|
|
||||||
var monoField = scriptField.[Friend]_monoField;
|
|
||||||
|
|
||||||
switch (scriptField.FieldType)
|
|
||||||
{
|
|
||||||
case .Float:
|
|
||||||
var value = GetData<float>(instance, scriptField);
|
|
||||||
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .Float, &value))
|
|
||||||
SetData(instance, scriptField, value);
|
|
||||||
|
|
||||||
case .Struct:
|
|
||||||
{
|
|
||||||
var v = Mono.mono_field_get_value_object(ScriptEngine.[Friend]s_AppDomain, scriptField.[Friend]_monoField, (.)instance);
|
|
||||||
|
|
||||||
void* dataPtr = Mono.mono_object_unbox(v);
|
|
||||||
|
|
||||||
Span<uint8> data = .((.)dataPtr, scriptField.SizeInBytes);
|
|
||||||
|
|
||||||
if (ImGui.CollapsingHeader(fieldName.Ptr))
|
|
||||||
{
|
|
||||||
DoFunnyStuff(dataPtr, scriptField.SharpType);
|
|
||||||
}
|
|
||||||
|
|
||||||
SetData<MonoObject>(instance, scriptField, v);
|
|
||||||
|
|
||||||
//Mono.mono_field_set_value_object(ScriptEngine.[Friend]s_AppDomain, scriptField.[Friend]_monoField, (.)instance);
|
|
||||||
//uint8* data = ;
|
|
||||||
|
|
||||||
/*uint8[] data = scope .[scriptField.SizeInBytes];
|
|
||||||
|
|
||||||
GetData(instance, scriptField, data.Ptr);
|
|
||||||
|
|
||||||
if (ImGui.CollapsingHeader(fieldName.Ptr))
|
|
||||||
{
|
|
||||||
DoFunnyStuff(data.Ptr, scriptField.SharpType);
|
|
||||||
}
|
|
||||||
|
|
||||||
MonoObject* boxed = Mono.mono_value_box(ScriptEngine.[Friend]s_AppDomain, ((SharpClass)scriptField.SharpType).[Friend]_monoClass, data.Ptr);
|
|
||||||
|
|
||||||
SetData<MonoObject>(instance, scriptField, boxed);*/
|
|
||||||
|
|
||||||
//Mono.mono_field_get_value(instance, scriptField.[Friend]_monoField, data.Ptr);
|
|
||||||
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
//Log.EngineLogger.Error($"Unhandled field type {scriptField.FieldType}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DoFunnyStuff(scriptInstance.[Friend]_instance, sharpClass);*/
|
|
||||||
|
|
||||||
for (let (fieldName, scriptField) in sharpClass.Fields)
|
for (let (fieldName, scriptField) in sharpClass.Fields)
|
||||||
{
|
{
|
||||||
var monoField = scriptField.[Friend]_monoField;
|
var monoField = scriptField.[Friend]_monoField;
|
||||||
@@ -672,22 +595,6 @@ namespace GlitchyEditor.EditWindows
|
|||||||
// TODO!
|
// TODO!
|
||||||
case .Struct:
|
case .Struct:
|
||||||
// TODO!
|
// TODO!
|
||||||
/*{
|
|
||||||
uint8[] data = scope .[scriptField.SizeInBytes];
|
|
||||||
|
|
||||||
Mono.mono_field_get_value(scriptInstance.[Friend]_instance, scriptField.[Friend]_monoField, data.Ptr);
|
|
||||||
|
|
||||||
//scriptField.
|
|
||||||
|
|
||||||
//scriptInstance.GetFieldValue();
|
|
||||||
|
|
||||||
//scriptInstance.ScriptClass.Fields[]
|
|
||||||
/*
|
|
||||||
var value = GetFieldValue<double>(scriptInstance, scriptField);
|
|
||||||
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .Double, &value))
|
|
||||||
SetFieldValue(scriptInstance, scriptField, value);
|
|
||||||
*/
|
|
||||||
}*/
|
|
||||||
default:
|
default:
|
||||||
Log.EngineLogger.Error($"Unhandled field type {scriptField.FieldType}");
|
Log.EngineLogger.Error($"Unhandled field type {scriptField.FieldType}");
|
||||||
}
|
}
|
||||||
@@ -697,311 +604,114 @@ namespace GlitchyEditor.EditWindows
|
|||||||
{
|
{
|
||||||
let scriptFields = ScriptEngine.GetScriptFieldMap(entity);
|
let scriptFields = ScriptEngine.GetScriptFieldMap(entity);
|
||||||
|
|
||||||
for (var (fieldName, field) in ref scriptFields)
|
for (var (name, field) in ref scriptFields)
|
||||||
{
|
{
|
||||||
switch (field.Type)
|
switch (field.Type)
|
||||||
{
|
{
|
||||||
case .Bool:
|
case .Bool:
|
||||||
var value = field.GetData<bool>();
|
var value = field.GetData<bool>();
|
||||||
if (ImGui.Checkbox(fieldName.CStr(), &value))
|
if (ImGui.Checkbox(name.CStr(), &value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
|
|
||||||
case .SByte:
|
case .SByte:
|
||||||
var value = field.GetData<int8>();
|
var value = field.GetData<int8>();
|
||||||
if (ImGui.DragScalar(fieldName.CStr(), .S8, &value))
|
if (ImGui.DragScalar(name.CStr(), .S8, &value))
|
||||||
field.SetData(value);
|
|
||||||
case .Short:
|
|
||||||
var value = field.GetData<int16>();
|
|
||||||
if (ImGui.DragScalar(fieldName.CStr(), .S16, &value))
|
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
|
case .Short:
|
||||||
|
var value = field.GetData<int16>();
|
||||||
|
if (ImGui.DragScalar(name.CStr(), .S16, &value))
|
||||||
|
field.SetData(value);
|
||||||
case .Int:
|
case .Int:
|
||||||
var value = field.GetData<int32>();
|
var value = field.GetData<int32>();
|
||||||
if (ImGui.DragScalar(fieldName.CStr(), .S32, &value))
|
if (ImGui.DragScalar(name.CStr(), .S32, &value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .Int2:
|
case .Int2:
|
||||||
var value = field.GetData<int2>();
|
var value = field.GetData<int2>();
|
||||||
if (ImGui.DragScalarN(fieldName.CStr(), .S32, &value, 2))
|
if (ImGui.DragScalarN(name.CStr(), .S32, &value, 2))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .Int3:
|
case .Int3:
|
||||||
var value = field.GetData<int3>();
|
var value = field.GetData<int3>();
|
||||||
if (ImGui.DragScalarN(fieldName.CStr(), .S32, &value, 3))
|
if (ImGui.DragScalarN(name.CStr(), .S32, &value, 3))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .Int4:
|
case .Int4:
|
||||||
var value = field.GetData<int4>();
|
var value = field.GetData<int4>();
|
||||||
if (ImGui.DragScalarN(fieldName.CStr(), .S32, &value, 4))
|
if (ImGui.DragScalarN(name.CStr(), .S32, &value, 4))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .Long:
|
case .Long:
|
||||||
var value = field.GetData<int64>();
|
var value = field.GetData<int64>();
|
||||||
if (ImGui.DragScalar(fieldName.CStr(), .S64, &value))
|
if (ImGui.DragScalar(name.CStr(), .S64, &value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
|
|
||||||
case .Byte:
|
case .Byte:
|
||||||
var value = field.GetData<uint8>();
|
var value = field.GetData<uint8>();
|
||||||
if (ImGui.DragScalar(fieldName.CStr(), .U8, &value))
|
if (ImGui.DragScalar(name.CStr(), .U8, &value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .UShort:
|
case .UShort:
|
||||||
var value = field.GetData<uint16>();
|
var value = field.GetData<uint16>();
|
||||||
if (ImGui.DragScalar(fieldName.CStr(), .U16, &value))
|
if (ImGui.DragScalar(name.CStr(), .U16, &value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .UInt:
|
case .UInt:
|
||||||
var value = field.GetData<uint32>();
|
var value = field.GetData<uint32>();
|
||||||
if (ImGui.DragScalar(fieldName.CStr(), .U32, &value))
|
if (ImGui.DragScalar(name.CStr(), .U32, &value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .ULong:
|
case .ULong:
|
||||||
var value = field.GetData<uint64>();
|
var value = field.GetData<uint64>();
|
||||||
if (ImGui.DragScalar(fieldName.CStr(), .U64, &value))
|
if (ImGui.DragScalar(name.CStr(), .U64, &value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
|
|
||||||
case .Float:
|
case .Float:
|
||||||
var value = field.GetData<float>();
|
var value = field.GetData<float>();
|
||||||
if (ImGui.DragScalar(fieldName.CStr(), .Float, &value))
|
if (ImGui.DragScalar(name.CStr(), .Float, &value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .float2:
|
case .float2:
|
||||||
var value = field.GetData<float2>();
|
var value = field.GetData<float2>();
|
||||||
if (ImGui.Editfloat2(fieldName, ref value))
|
if (ImGui.Editfloat2(name, ref value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .float3:
|
case .float3:
|
||||||
var value = field.GetData<float3>();
|
var value = field.GetData<float3>();
|
||||||
if (ImGui.Editfloat3(fieldName, ref value))
|
if (ImGui.Editfloat3(name, ref value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .float4:
|
case .float4:
|
||||||
var value = field.GetData<float4>();
|
var value = field.GetData<float4>();
|
||||||
if (ImGui.Editfloat4(fieldName, ref value))
|
if (ImGui.Editfloat4(name, ref value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
|
|
||||||
case .Double:
|
case .Double:
|
||||||
var value = field.GetData<double>();
|
var value = field.GetData<double>();
|
||||||
if (ImGui.DragScalar(fieldName.CStr(), .Double, &value))
|
if (ImGui.DragScalar(name.CStr(), .Double, &value))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .Double2:
|
case .Double2:
|
||||||
var value = field.GetData<double2>();
|
var value = field.GetData<double2>();
|
||||||
if (ImGui.DragScalarN(fieldName.CStr(), .Double, &value, 2))
|
if (ImGui.DragScalarN(name.CStr(), .Double, &value, 2))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .Double3:
|
case .Double3:
|
||||||
var value = field.GetData<double3>();
|
var value = field.GetData<double3>();
|
||||||
if (ImGui.DragScalarN(fieldName.CStr(), .Double, &value, 3))
|
if (ImGui.DragScalarN(name.CStr(), .Double, &value, 3))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
case .Double4:
|
case .Double4:
|
||||||
var value = field.GetData<double4>();
|
var value = field.GetData<double4>();
|
||||||
if (ImGui.DragScalarN(fieldName.CStr(), .Double, &value, 4))
|
if (ImGui.DragScalarN(name.CStr(), .Double, &value, 4))
|
||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
|
|
||||||
case .Enum:
|
case .Enum:
|
||||||
ShowEnumSelector(field, fieldName, scriptClass);
|
// TODO!
|
||||||
|
|
||||||
//case .String:
|
//case .String:
|
||||||
// TODO!
|
// TODO!
|
||||||
|
|
||||||
case .Entity:
|
case .Entity:
|
||||||
ShowEntityReceiver(field, fieldName, scriptClass);
|
// TODO!
|
||||||
case .Component:
|
|
||||||
ShowComponentReceiver(field, fieldName, scriptClass);
|
|
||||||
|
|
||||||
case .Struct:
|
case .Struct:
|
||||||
// TODO!
|
// TODO!
|
||||||
|
|
||||||
case .Class:
|
|
||||||
// We don't support editing classes
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Log.EngineLogger.Error($"Unhandled field type {field.Type}");
|
Log.EngineLogger.Error($"Unhandled field type {field.Type}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private static void ShowEnumSelector(ScriptFieldInstance* field, StringView fieldName, ScriptClass scriptClass)
|
*/
|
||||||
{
|
|
||||||
ScriptField scriptField = scriptClass.Fields[fieldName];
|
|
||||||
SharpEnum enumType = scriptField.SharpType as SharpEnum;
|
|
||||||
|
|
||||||
Log.EngineLogger.Assert(enumType != null, "Enum must have a SharpEnum!");
|
|
||||||
|
|
||||||
// Simply get Enum as a uint64
|
|
||||||
var fieldValue = field.GetData<uint64>();
|
|
||||||
|
|
||||||
StringView valueName = "<Invalid Value>";
|
|
||||||
|
|
||||||
if (enumType.Values.TryGetValue(fieldValue, let enumValue))
|
|
||||||
valueName = enumValue.Name;
|
|
||||||
|
|
||||||
if (ImGui.BeginCombo(fieldName.Ptr, valueName.Ptr))
|
|
||||||
{
|
|
||||||
for (let (entryValue, enumEntry) in enumType.Values)
|
|
||||||
{
|
|
||||||
if (ImGui.Selectable(enumEntry.Name.Ptr, fieldValue == entryValue))
|
|
||||||
field.SetData(entryValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndCombo();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Entity? ShowEntitySelector()
|
|
||||||
{
|
|
||||||
static char8[128] entitySearch = .();
|
|
||||||
|
|
||||||
Entity? result = null;
|
|
||||||
|
|
||||||
if (ImGui.BeginPopup("ENTITY_SELECTOR"))
|
|
||||||
{
|
|
||||||
ImGui.TextUnformatted("Search:");
|
|
||||||
ImGui.SameLine();
|
|
||||||
|
|
||||||
if (ImGui.InputText("##entitySearcher", &entitySearch, (uint64)entitySearch.Count))
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndPopup();
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ShowEntityReceiver(ScriptFieldInstance* field, StringView fieldName, ScriptClass scriptClass)
|
|
||||||
{
|
|
||||||
var entityId = field.GetData<UUID>();
|
|
||||||
|
|
||||||
Result<Entity> fieldEntity = Editor.Instance.CurrentScene.GetEntityByID(entityId);
|
|
||||||
|
|
||||||
String entityName = scope .(32);
|
|
||||||
|
|
||||||
if (entityId == UUID(0))
|
|
||||||
entityName.Set("None");
|
|
||||||
else if (fieldEntity case .Ok(Entity e))
|
|
||||||
entityName.Set(e.Name);
|
|
||||||
else
|
|
||||||
entityName..Clear().AppendF($"Missing entity ({entityId})");
|
|
||||||
|
|
||||||
ImGui.Text($"{fieldName}: ");
|
|
||||||
ImGui.SameLine();
|
|
||||||
|
|
||||||
if (ImGui.Button(entityName))
|
|
||||||
{
|
|
||||||
if (fieldEntity case .Ok)
|
|
||||||
Editor.Instance.EntityHierarchyWindow.HighlightEntity(fieldEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
|
||||||
{
|
|
||||||
ImGui.Payload* peekPayload = ImGui.AcceptDragDropPayload(.Entity, .AcceptPeekOnly);
|
|
||||||
|
|
||||||
bool allowDrop = false;
|
|
||||||
|
|
||||||
if (peekPayload != null)
|
|
||||||
{
|
|
||||||
Entity draggedEntity = *(Entity*)peekPayload.Data;
|
|
||||||
|
|
||||||
ScriptClass draggedScriptClass = ScriptEngine.[Friend]s_EntityRoot;
|
|
||||||
|
|
||||||
if (draggedEntity.TryGetComponent<ScriptComponent>(let draggedScript))
|
|
||||||
{
|
|
||||||
var draggedClassName = draggedScript.ScriptClassName;
|
|
||||||
draggedScriptClass = ScriptEngine.GetScriptClass(draggedClassName);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: I don't like the fact, that we are using mono directly
|
|
||||||
|
|
||||||
ScriptField scriptField = scriptClass.Fields[fieldName];
|
|
||||||
var fieldMonoClass = Mono.mono_type_get_class(scriptField.GetMonoType());
|
|
||||||
|
|
||||||
allowDrop = draggedScriptClass.[Friend]IsSubclass(fieldMonoClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allowDrop)
|
|
||||||
{
|
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.Entity);
|
|
||||||
|
|
||||||
if (payload != null)
|
|
||||||
{
|
|
||||||
Log.EngineLogger.AssertDebug(payload.DataSize == sizeof(Entity));
|
|
||||||
|
|
||||||
Entity droppedEntity = *(Entity*)payload.Data;
|
|
||||||
|
|
||||||
if (droppedEntity.IsValid)
|
|
||||||
field.SetData<UUID>(droppedEntity.UUID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndDragDropTarget();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//private static Entity?
|
|
||||||
|
|
||||||
private static void ShowComponentReceiver(ScriptFieldInstance* field, StringView fieldName, ScriptClass scriptClass)
|
|
||||||
{
|
|
||||||
var entityId = field.GetData<UUID>();
|
|
||||||
|
|
||||||
Result<Entity> fieldEntity = Editor.Instance.CurrentScene.GetEntityByID(entityId);
|
|
||||||
|
|
||||||
String entityName = scope .(32);
|
|
||||||
|
|
||||||
if (entityId == UUID(0))
|
|
||||||
entityName.Set("None");
|
|
||||||
else if (fieldEntity case .Ok(Entity e))
|
|
||||||
entityName.Set(e.Name);
|
|
||||||
else
|
|
||||||
entityName..Clear().AppendF($"Missing reference ({entityId})");
|
|
||||||
|
|
||||||
ImGui.Text($"{fieldName}: ");
|
|
||||||
ImGui.SameLine();
|
|
||||||
|
|
||||||
if (ImGui.Button(entityName))
|
|
||||||
{
|
|
||||||
if (fieldEntity case .Ok)
|
|
||||||
Editor.Instance.EntityHierarchyWindow.HighlightEntity(fieldEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
|
||||||
{
|
|
||||||
ImGui.Payload* peekPayload = ImGui.AcceptDragDropPayload(.Entity, .AcceptPeekOnly);
|
|
||||||
|
|
||||||
bool allowDrop = false;
|
|
||||||
|
|
||||||
if (peekPayload != null)
|
|
||||||
{
|
|
||||||
Entity draggedEntity = *(Entity*)peekPayload.Data;
|
|
||||||
|
|
||||||
// TODO: I don't like the fact, that we are using mono directly
|
|
||||||
|
|
||||||
ScriptField scriptField = scriptClass.Fields[fieldName];
|
|
||||||
|
|
||||||
// For some reason we have to retrieve the MonoType like this. Using scriptField.GetMonoType() directly returns the wrong type...
|
|
||||||
MonoReflectionType* reflectionType = Mono.mono_type_get_object(ScriptEngine.[Friend]s_AppDomain, scriptField.GetMonoType());
|
|
||||||
MonoType* actualMonoType = Mono.mono_reflection_type_get_type(reflectionType);
|
|
||||||
|
|
||||||
// TODO: We shouldn't abuse the script glue like that.
|
|
||||||
// ScriptGlue should only be called by C#, not by Beef.
|
|
||||||
if (ScriptGlue.[Friend]s_HasComponentMethods.TryGetValue(actualMonoType, let has_component))
|
|
||||||
{
|
|
||||||
allowDrop = has_component(draggedEntity);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Warning($"No HasComponent-Function found for field {scriptField.Name}");
|
|
||||||
allowDrop = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allowDrop)
|
|
||||||
{
|
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.Entity);
|
|
||||||
|
|
||||||
if (payload != null)
|
|
||||||
{
|
|
||||||
Log.EngineLogger.AssertDebug(payload.DataSize == sizeof(Entity));
|
|
||||||
|
|
||||||
Entity droppedEntity = *(Entity*)payload.Data;
|
|
||||||
|
|
||||||
if (droppedEntity.IsValid)
|
|
||||||
field.SetData<UUID>(droppedEntity.UUID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndDragDropTarget();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void LabelColumn(StringView label)
|
private static void LabelColumn(StringView label)
|
||||||
@@ -1068,7 +778,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
if (ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
||||||
|
|
||||||
if (payload != null)
|
if (payload != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
SubTexture2D image = s_FolderTexture;
|
SubTexture2D image = s_FolderTexture;
|
||||||
|
|
||||||
ImGui.ImageButton("", image, (.)(DirectoryItemSize - padding));
|
ImGui.ImageButton(image, (.)(DirectoryItemSize - padding));
|
||||||
|
|
||||||
ImGui.PopStyleColor();
|
ImGui.PopStyleColor();
|
||||||
|
|
||||||
@@ -310,7 +310,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
// TODO: preview images
|
// TODO: preview images
|
||||||
SubTexture2D image = entry->IsDirectory ? s_FolderTexture : s_FileTexture;
|
SubTexture2D image = entry->IsDirectory ? s_FolderTexture : s_FileTexture;
|
||||||
|
|
||||||
ImGui.ImageButton("FileImage", image, (.)(DirectoryItemSize - padding));
|
ImGui.ImageButton(image, (.)(DirectoryItemSize - padding));
|
||||||
|
|
||||||
ImGui.PopStyleColor();
|
ImGui.PopStyleColor();
|
||||||
|
|
||||||
@@ -324,7 +324,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
Path.Fixup(fullpath);
|
Path.Fixup(fullpath);
|
||||||
|
|
||||||
ImGui.SetDragDropPayload(.ContentBrowserItem, fullpath.CStr(), (.)fullpath.Length, .Once);
|
ImGui.SetDragDropPayload("CONTENT_BROWSER_ITEM", fullpath.CStr(), (.)fullpath.Length, .Once);
|
||||||
|
|
||||||
ImGui.EndDragDropSource();
|
ImGui.EndDragDropSource();
|
||||||
}
|
}
|
||||||
@@ -370,7 +370,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
String fullpath = scope String(entry->Path);
|
String fullpath = scope String(entry->Path);
|
||||||
fullpath.AppendF($"#{subAsset.Name}");
|
fullpath.AppendF($"#{subAsset.Name}");
|
||||||
|
|
||||||
ImGui.SetDragDropPayload(.ContentBrowserItem, fullpath.CStr(), (.)fullpath.Length, .Once);
|
ImGui.SetDragDropPayload("CONTENT_BROWSER_ITEM", fullpath.CStr(), (.)fullpath.Length, .Once);
|
||||||
|
|
||||||
ImGui.EndDragDropSource();
|
ImGui.EndDragDropSource();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
{
|
{
|
||||||
if (ImGui.BeginDragDropTarget())
|
if (ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
||||||
|
|
||||||
if (payload != null)
|
if (payload != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,26 +21,8 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
private List<Entity> _selectedEntities = new .() ~ delete _;
|
private List<Entity> _selectedEntities = new .() ~ delete _;
|
||||||
|
|
||||||
private Entity _entityToHighlight;
|
|
||||||
|
|
||||||
public List<Entity> SelectedEntities => _selectedEntities;
|
public List<Entity> SelectedEntities => _selectedEntities;
|
||||||
|
|
||||||
private List<Entity> _entitiesToUnfold = new .() ~ delete _;
|
|
||||||
|
|
||||||
public void HighlightEntity(Entity e)
|
|
||||||
{
|
|
||||||
_entityToHighlight = e;
|
|
||||||
|
|
||||||
Entity walker = _entityToHighlight;
|
|
||||||
|
|
||||||
while (walker.Parent != null)
|
|
||||||
{
|
|
||||||
walker = walker.Parent.Value;
|
|
||||||
|
|
||||||
_entitiesToUnfold.Add(walker);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(Editor editor, Scene scene)
|
public this(Editor editor, Scene scene)
|
||||||
{
|
{
|
||||||
_editor = editor;
|
_editor = editor;
|
||||||
@@ -340,21 +322,8 @@ namespace GlitchyEditor.EditWindows
|
|||||||
if(inSelectedList)
|
if(inSelectedList)
|
||||||
flags |= .Selected;
|
flags |= .Selected;
|
||||||
|
|
||||||
if (_entitiesToUnfold.Contains(tree.Value))
|
|
||||||
{
|
|
||||||
_entitiesToUnfold.Remove(tree.Value);
|
|
||||||
|
|
||||||
ImGui.SetNextItemOpen(true, .None);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isOpen = ImGui.TreeNodeEx((void*)(uint)tree.Value.Handle.[Friend]Index, flags, $"{name}");
|
bool isOpen = ImGui.TreeNodeEx((void*)(uint)tree.Value.Handle.[Friend]Index, flags, $"{name}");
|
||||||
|
|
||||||
if (_entityToHighlight == tree.Value)
|
|
||||||
{
|
|
||||||
ImGui.SetScrollHereY(0);
|
|
||||||
_entityToHighlight = .();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.PushID((void*)(uint)tree.Value.Handle.[Friend]Index);
|
ImGui.PushID((void*)(uint)tree.Value.Handle.[Friend]Index);
|
||||||
|
|
||||||
bool deleted = false;
|
bool deleted = false;
|
||||||
@@ -372,13 +341,9 @@ namespace GlitchyEditor.EditWindows
|
|||||||
if (deleted)
|
if (deleted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool isDragged = false;
|
|
||||||
|
|
||||||
if(ImGui.BeginDragDropSource())
|
if(ImGui.BeginDragDropSource())
|
||||||
{
|
{
|
||||||
isDragged = true;
|
ImGui.SetDragDropPayload("DND_Entity", &tree.Value, sizeof(Entity));
|
||||||
|
|
||||||
ImGui.SetDragDropPayload(.Entity, &tree.Value, sizeof(Entity));
|
|
||||||
|
|
||||||
ImGui.Text(name);
|
ImGui.Text(name);
|
||||||
|
|
||||||
@@ -387,7 +352,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
if(ImGui.BeginDragDropTarget())
|
if(ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.Entity);
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("DND_Entity");
|
||||||
|
|
||||||
if(payload != null)
|
if(payload != null)
|
||||||
{
|
{
|
||||||
@@ -430,7 +395,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
bool clicked = ImGui.IsItemClicked(.Left);
|
bool clicked = ImGui.IsItemClicked(.Left);
|
||||||
bool clickedRight = ImGui.IsItemClicked(.Right);
|
bool clickedRight = ImGui.IsItemClicked(.Right);
|
||||||
|
|
||||||
if(isOpen)
|
if(isOpen)
|
||||||
{
|
{
|
||||||
for(var child in tree.Children)
|
for(var child in tree.Children)
|
||||||
@@ -442,12 +407,6 @@ namespace GlitchyEditor.EditWindows
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (clicked || clickedRight)
|
if (clicked || clickedRight)
|
||||||
{
|
|
||||||
lastClickedEntity = tree.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if (!isDragged && (clicked || clickedRight))
|
|
||||||
if (!isDragged && (!ImGui.IsMouseDown(.Left) && !ImGui.IsMouseDown(.Right) && ImGui.IsItemHovered()) && tree.Value == lastClickedEntity)
|
|
||||||
{
|
{
|
||||||
if (inSelectedList && !clickedRight)
|
if (inSelectedList && !clickedRight)
|
||||||
{
|
{
|
||||||
@@ -459,13 +418,9 @@ namespace GlitchyEditor.EditWindows
|
|||||||
SelectEntity(tree.Value, !ImGui.GetIO().KeyCtrl && !clickedRight);
|
SelectEntity(tree.Value, !ImGui.GetIO().KeyCtrl && !clickedRight);
|
||||||
inSelectedList = true;
|
inSelectedList = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastClickedEntity = .();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Entity lastClickedEntity;
|
|
||||||
|
|
||||||
private void ShowEntityHierarchy()
|
private void ShowEntityHierarchy()
|
||||||
{
|
{
|
||||||
StringView searchString = StringView(&_entitySearchChars);
|
StringView searchString = StringView(&_entitySearchChars);
|
||||||
@@ -509,7 +464,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
{
|
{
|
||||||
if(ImGui.BeginDragDropTarget())
|
if(ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.Entity);
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("DND_Entity");
|
||||||
|
|
||||||
if(payload != null)
|
if(payload != null)
|
||||||
{
|
{
|
||||||
@@ -572,10 +527,6 @@ namespace GlitchyEditor.EditWindows
|
|||||||
ImGuiPrintEntityTree(scope .(entity));
|
ImGuiPrintEntityTree(scope .(entity));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the mouse was released and no entity took the chance to become selected we probably hovered the background while releasing -> select no entity
|
|
||||||
if (!ImGui.IsMouseDown(.Left) && !ImGui.IsMouseDown(.Right))
|
|
||||||
lastClickedEntity = .();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
{
|
{
|
||||||
if (ImGui.BeginDragDropTarget())
|
if (ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
||||||
|
|
||||||
if (payload != null)
|
if (payload != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,375 +0,0 @@
|
|||||||
using System;
|
|
||||||
using ImGui;
|
|
||||||
using System.Collections;
|
|
||||||
using GlitchyEngine.Core;
|
|
||||||
using GlitchyEngine.World;
|
|
||||||
using GlitchLog;
|
|
||||||
using GlitchyEngine.Scripting;
|
|
||||||
using GlitchyEngine.Renderer;
|
|
||||||
|
|
||||||
namespace GlitchyEditor.EditWindows;
|
|
||||||
|
|
||||||
enum MessageType
|
|
||||||
{
|
|
||||||
case None = 0;
|
|
||||||
case Trace = 1;
|
|
||||||
case Info = 2;
|
|
||||||
case Warning = 4;
|
|
||||||
case Error = 8;
|
|
||||||
|
|
||||||
public this(LogLevel level)
|
|
||||||
{
|
|
||||||
switch (level)
|
|
||||||
{
|
|
||||||
case .Error:
|
|
||||||
this = Error;
|
|
||||||
case .Warning:
|
|
||||||
this = Warning;
|
|
||||||
case .Info:
|
|
||||||
this = Info;
|
|
||||||
case .Trace:
|
|
||||||
this = Trace;
|
|
||||||
default:
|
|
||||||
this = None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class MessageSource
|
|
||||||
{
|
|
||||||
public UUID? Entity = null;
|
|
||||||
public StringView? ScriptName = null;
|
|
||||||
public int? Line = null;
|
|
||||||
|
|
||||||
/// If true, the message is only meant for engine developers... so only me :(
|
|
||||||
public bool IsEngineMessage = false;
|
|
||||||
|
|
||||||
public MonoExceptionHelper Exception = null ~ _?.ReleaseRef();
|
|
||||||
|
|
||||||
public String AdditionalData = null ~ delete _;
|
|
||||||
}
|
|
||||||
|
|
||||||
class LogMessage
|
|
||||||
{
|
|
||||||
private String _message ~ delete _;
|
|
||||||
|
|
||||||
public MessageType MessageType { get; private set; }
|
|
||||||
|
|
||||||
public DateTime Timestamp { get; private set; }
|
|
||||||
|
|
||||||
public MessageSource Source { get; private set; } ~ delete _;
|
|
||||||
|
|
||||||
public StringView Message => _message;
|
|
||||||
|
|
||||||
public this(DateTime timestamp, StringView message, MessageType logLevel, MessageSource ownSource)
|
|
||||||
{
|
|
||||||
Timestamp = timestamp;
|
|
||||||
_message = new String(message);
|
|
||||||
MessageType = logLevel;
|
|
||||||
Source = ownSource;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class LogWindow : EditorWindow
|
|
||||||
{
|
|
||||||
public const String s_WindowTitle = "Log";
|
|
||||||
|
|
||||||
private append List<LogMessage> _messages = .() ~ ClearAndDeleteItems!(_);
|
|
||||||
|
|
||||||
public static SubTexture2D s_ErrorIcon;
|
|
||||||
public static SubTexture2D s_WarningIcon;
|
|
||||||
public static SubTexture2D s_InfoIcon;
|
|
||||||
public static SubTexture2D s_TraceIcon;
|
|
||||||
|
|
||||||
private bool _showGameMessages = true;
|
|
||||||
private bool _showEngineMessages = false;
|
|
||||||
private bool _autoScroll = true;
|
|
||||||
private bool _collapseMessages = true;
|
|
||||||
|
|
||||||
private MessageType _visibleMessageTypes = .Error | .Warning | .Info | .Trace;
|
|
||||||
|
|
||||||
protected override void InternalShow()
|
|
||||||
{
|
|
||||||
defer { ImGui.End(); }
|
|
||||||
if(!ImGui.Begin(s_WindowTitle, &_open, .MenuBar))
|
|
||||||
return;
|
|
||||||
|
|
||||||
ShowMenuBar();
|
|
||||||
|
|
||||||
ShowMessages();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShowMenuBar()
|
|
||||||
{
|
|
||||||
if(ImGui.BeginMenuBar())
|
|
||||||
{
|
|
||||||
if (ImGui.MenuItem("Clear"))
|
|
||||||
{
|
|
||||||
ClearLog();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.BeginMenu("Filter"))
|
|
||||||
{
|
|
||||||
ImGui.Checkbox("Show game messages", &_showGameMessages);
|
|
||||||
ImGui.AttachTooltip("If checked, the log will show messages generated by the game (e.g. scripts).");
|
|
||||||
|
|
||||||
ImGui.Checkbox("Show engine messages", &_showEngineMessages);
|
|
||||||
ImGui.AttachTooltip("""
|
|
||||||
If checked, the log will show messages generated by the engine.
|
|
||||||
These messages are usually only necessary for engine debugging/development and don't provide practical information for game developers.
|
|
||||||
""");
|
|
||||||
|
|
||||||
ImGui.EndMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.Checkbox("Collapse", &_collapseMessages);
|
|
||||||
ImGui.AttachTooltip("If checked, identical messages will be collapsed into one.");
|
|
||||||
|
|
||||||
var maxSpace = ImGui.GetFontSize();
|
|
||||||
|
|
||||||
ImGui.Vec2 buttonSize = .(maxSpace, maxSpace);
|
|
||||||
|
|
||||||
var col = ImGui.GetStyleColorVec4(.Button);
|
|
||||||
ImGui.PushStyleVar(.FramePadding, ImGui.Vec2(2, 2));
|
|
||||||
|
|
||||||
if (_visibleMessageTypes.HasFlag(.Trace))
|
|
||||||
ImGui.PushStyleColor(.Button, *col);
|
|
||||||
else
|
|
||||||
ImGui.PushStyleColor(.Button, .(0, 0, 0, 0));
|
|
||||||
|
|
||||||
if (ImGui.ImageButtonEx(1, s_TraceIcon, buttonSize, .Zero, .Ones))
|
|
||||||
_visibleMessageTypes ^= .Trace;
|
|
||||||
|
|
||||||
ImGui.PopStyleColor();
|
|
||||||
|
|
||||||
if (_visibleMessageTypes.HasFlag(.Info))
|
|
||||||
ImGui.PushStyleColor(.Button, *col);
|
|
||||||
else
|
|
||||||
ImGui.PushStyleColor(.Button, .(0, 0, 0, 0));
|
|
||||||
|
|
||||||
if (ImGui.ImageButtonEx(2, s_InfoIcon, buttonSize, .Zero, .Ones))
|
|
||||||
_visibleMessageTypes ^= .Info;
|
|
||||||
|
|
||||||
ImGui.PopStyleColor();
|
|
||||||
|
|
||||||
if (_visibleMessageTypes.HasFlag(.Warning))
|
|
||||||
ImGui.PushStyleColor(.Button, *col);
|
|
||||||
else
|
|
||||||
ImGui.PushStyleColor(.Button, .(0, 0, 0, 0));
|
|
||||||
|
|
||||||
if (ImGui.ImageButtonEx(3, s_WarningIcon, buttonSize, .Zero, .Ones))
|
|
||||||
_visibleMessageTypes ^= .Warning;
|
|
||||||
|
|
||||||
ImGui.PopStyleColor();
|
|
||||||
|
|
||||||
if (_visibleMessageTypes.HasFlag(.Error))
|
|
||||||
ImGui.PushStyleColor(.Button, *col);
|
|
||||||
else
|
|
||||||
ImGui.PushStyleColor(.Button, .(0, 0, 0, 0));
|
|
||||||
|
|
||||||
|
|
||||||
if (ImGui.ImageButtonEx(4, s_ErrorIcon, buttonSize, .Zero, .Ones))
|
|
||||||
_visibleMessageTypes ^= .Error;
|
|
||||||
|
|
||||||
ImGui.PopStyleColor();
|
|
||||||
|
|
||||||
ImGui.PopStyleVar();
|
|
||||||
|
|
||||||
ImGui.EndMenuBar();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShowMessages()
|
|
||||||
{
|
|
||||||
if (ImGui.BeginTable("Messages", 3, .BordersInnerH | .SizingFixedFit))
|
|
||||||
{
|
|
||||||
ImGui.TableSetupColumn("", .WidthFixed);
|
|
||||||
ImGui.TableSetupColumn("", .WidthStretch);
|
|
||||||
ImGui.TableSetupColumn("", .WidthFixed);
|
|
||||||
|
|
||||||
//LogMessage lastMessage = null;
|
|
||||||
int count = 1;
|
|
||||||
|
|
||||||
// Message ID for ImGui
|
|
||||||
int imGuiMessageId = 0;
|
|
||||||
|
|
||||||
for (let message in _messages)
|
|
||||||
{
|
|
||||||
if (!_visibleMessageTypes.HasFlag(message.MessageType))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((message.Source.IsEngineMessage && !_showEngineMessages) || (!message.Source.IsEngineMessage && !_showGameMessages))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/*defer
|
|
||||||
{
|
|
||||||
lastMessage = message;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
LogMessage lastMessage = (message != _messages.Back) ? _messages[@message.Index + 1] : null;
|
|
||||||
|
|
||||||
if (_collapseMessages && lastMessage != null)
|
|
||||||
{
|
|
||||||
if (message.MessageType != lastMessage.MessageType)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (message.Message != lastMessage.Message)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (message.Source.Entity != lastMessage.Source.Entity)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// For exceptions the stack trace is basically the only relevant thing
|
|
||||||
if (message.Source.Exception?.StackTrace != lastMessage.Source.Exception?.StackTrace)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// We collapse this message with the previous one:
|
|
||||||
// Increment counter and go to next message.
|
|
||||||
count++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Push current index as ID
|
|
||||||
ImGui.PushID((void*)++imGuiMessageId);
|
|
||||||
|
|
||||||
ImGui.TableNextRow();
|
|
||||||
ImGui.TableSetColumnIndex(0);
|
|
||||||
|
|
||||||
switch (message.MessageType)
|
|
||||||
{
|
|
||||||
case .Error:
|
|
||||||
ImGui.Image(s_ErrorIcon, ImGui.Vec2(32, 32));
|
|
||||||
ImGui.AttachTooltip("Error");
|
|
||||||
case .Warning:
|
|
||||||
ImGui.Image(s_WarningIcon, ImGui.Vec2(32, 32));
|
|
||||||
ImGui.AttachTooltip("Warning");
|
|
||||||
case .Info:
|
|
||||||
ImGui.Image(s_InfoIcon, ImGui.Vec2(32, 32));
|
|
||||||
ImGui.AttachTooltip("Info");
|
|
||||||
case .Trace:
|
|
||||||
ImGui.Image(s_TraceIcon, ImGui.Vec2(32, 32));
|
|
||||||
ImGui.AttachTooltip("Trace");
|
|
||||||
default:
|
|
||||||
ImGui.TextUnformatted("Unknown");
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
|
|
||||||
// Timestamp
|
|
||||||
ImGui.TextWrapped($"[{message.Timestamp:HH:mm:ss.fff}]");
|
|
||||||
|
|
||||||
if (message.Source.IsEngineMessage)
|
|
||||||
{
|
|
||||||
ImGui.SameLine();
|
|
||||||
ImGui.TextUnformatted("Engine");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show entity
|
|
||||||
if (message.Source?.Entity != null)
|
|
||||||
{
|
|
||||||
ImGui.SameLine();
|
|
||||||
|
|
||||||
Result<Entity> entity = Editor.Instance.CurrentScene.GetEntityByID(message.Source.Entity.Value);
|
|
||||||
|
|
||||||
if (entity case .Ok(let e))
|
|
||||||
{
|
|
||||||
ImGui.Text($"Entity: \"{e.Name}\" (ID: {message.Source.Entity})");
|
|
||||||
|
|
||||||
if (ImGui.IsItemClicked())
|
|
||||||
Editor.Instance.EntityHierarchyWindow.HighlightEntity(entity);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ImGui.Text($"Entity: (ID: {message.Source.Entity})");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.Source.Exception != null)
|
|
||||||
{
|
|
||||||
if (ImGui.CollapsingHeader(message.Message.Ptr))
|
|
||||||
{
|
|
||||||
// Show the native to managed entry point only if we show engine messages
|
|
||||||
|
|
||||||
if (_showEngineMessages)
|
|
||||||
ImGui.TextUnformatted(message.Source.Exception.StackTrace);
|
|
||||||
else
|
|
||||||
ImGui.TextUnformatted(message.Source.Exception.CleanStackTrace);
|
|
||||||
|
|
||||||
ImGui.NewLine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ImGui.TextUnformatted(message.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dont show the counter if we only have one message.
|
|
||||||
if (count > 1)
|
|
||||||
{
|
|
||||||
// the message is not collapsible with the previous one.
|
|
||||||
// Print message count for last message and reset counter.
|
|
||||||
// This message will be printed normally.
|
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text($"{count}");
|
|
||||||
}
|
|
||||||
|
|
||||||
count = 1;
|
|
||||||
|
|
||||||
ImGui.PopID();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_autoScroll)
|
|
||||||
{
|
|
||||||
if (ImGui.GetIO().MouseWheel > 0)
|
|
||||||
{
|
|
||||||
_autoScroll = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ImGui.SetScrollY(ImGui.GetScrollMaxY());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (ImGui.GetScrollMaxY() == ImGui.GetScrollY())
|
|
||||||
{
|
|
||||||
_autoScroll = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndTable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ClearLog()
|
|
||||||
{
|
|
||||||
ClearAndDeleteItems!(_messages);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Log(DateTime timestamp, LogLevel severity, StringView message, MessageSource source)
|
|
||||||
{
|
|
||||||
LogMessage logMessage = new LogMessage(timestamp, message, MessageType(severity), source);
|
|
||||||
_messages.Add(logMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LogException(DateTime timestamp, MonoExceptionHelper exception)
|
|
||||||
{
|
|
||||||
StringView firstLine = exception.StackTrace;
|
|
||||||
|
|
||||||
int firstInIndex = exception.StackTrace.IndexOf("\n");
|
|
||||||
|
|
||||||
if (firstInIndex != -1)
|
|
||||||
firstLine = firstLine.Substring(0, firstInIndex);
|
|
||||||
|
|
||||||
String message = scope .(128);
|
|
||||||
message.AppendF($"Exception: \"{exception.FullName}\" | Message: \"{exception.Message}\" {firstLine}\0");
|
|
||||||
|
|
||||||
// TODO: are mono exceptions never engine only?
|
|
||||||
LogMessage logMessage = new LogMessage(timestamp, message, .Error, new MessageSource(){Entity = exception.Instance, Exception = exception..AddRef(), IsEngineMessage = false});
|
|
||||||
_messages.Add(logMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -22,7 +22,6 @@ namespace GlitchyEditor
|
|||||||
private ContentBrowserWindow _contentBrowserWindow ~ delete _;
|
private ContentBrowserWindow _contentBrowserWindow ~ delete _;
|
||||||
private PropertiesWindow _propertiesWindow ~ delete _;
|
private PropertiesWindow _propertiesWindow ~ delete _;
|
||||||
private AssetViewer _assetViewer ~ delete _;
|
private AssetViewer _assetViewer ~ delete _;
|
||||||
private LogWindow _logWindow ~ delete _;
|
|
||||||
|
|
||||||
public Scene CurrentScene
|
public Scene CurrentScene
|
||||||
{
|
{
|
||||||
@@ -46,7 +45,6 @@ namespace GlitchyEditor
|
|||||||
public ContentBrowserWindow ContentBrowserWindow => _contentBrowserWindow;
|
public ContentBrowserWindow ContentBrowserWindow => _contentBrowserWindow;
|
||||||
public PropertiesWindow PropertiesWindow => _propertiesWindow;
|
public PropertiesWindow PropertiesWindow => _propertiesWindow;
|
||||||
public AssetViewer AssetViewer => _assetViewer;
|
public AssetViewer AssetViewer => _assetViewer;
|
||||||
public LogWindow LogWindow => _logWindow;
|
|
||||||
|
|
||||||
public EditorCamera* CurrentCamera { get; set; }
|
public EditorCamera* CurrentCamera { get; set; }
|
||||||
|
|
||||||
@@ -55,27 +53,15 @@ namespace GlitchyEditor
|
|||||||
public SceneRenderer GameSceneRenderer {get; set;}
|
public SceneRenderer GameSceneRenderer {get; set;}
|
||||||
public SceneRenderer EditorSceneRenderer {get; set;}
|
public SceneRenderer EditorSceneRenderer {get; set;}
|
||||||
|
|
||||||
private static Editor s_Instance;
|
|
||||||
|
|
||||||
public static Editor Instance => s_Instance;
|
|
||||||
|
|
||||||
/// Creates a new editor for the given world
|
/// Creates a new editor for the given world
|
||||||
public this(Scene scene, EditorContentManager contentManager)
|
public this(Scene scene, EditorContentManager contentManager)
|
||||||
{
|
{
|
||||||
Log.EngineLogger.AssertDebug(s_Instance == null, "Cannot create a second instance of a singleton.");
|
|
||||||
s_Instance = this;
|
|
||||||
|
|
||||||
_scene = scene;
|
_scene = scene;
|
||||||
_contentManager = contentManager;
|
_contentManager = contentManager;
|
||||||
|
|
||||||
InitWindows();
|
InitWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ~this()
|
|
||||||
{
|
|
||||||
s_Instance = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitWindows()
|
private void InitWindows()
|
||||||
{
|
{
|
||||||
_sceneViewportWindow = new EditorViewportWindow(this);
|
_sceneViewportWindow = new EditorViewportWindow(this);
|
||||||
@@ -85,7 +71,6 @@ namespace GlitchyEditor
|
|||||||
_contentBrowserWindow = new ContentBrowserWindow((.)Application.Get().ContentManager);
|
_contentBrowserWindow = new ContentBrowserWindow((.)Application.Get().ContentManager);
|
||||||
_propertiesWindow = new PropertiesWindow(this);
|
_propertiesWindow = new PropertiesWindow(this);
|
||||||
_assetViewer = new AssetViewer((.)Application.Get().ContentManager);
|
_assetViewer = new AssetViewer((.)Application.Get().ContentManager);
|
||||||
_logWindow = new LogWindow();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
@@ -97,7 +82,6 @@ namespace GlitchyEditor
|
|||||||
_contentBrowserWindow.Show();
|
_contentBrowserWindow.Show();
|
||||||
_propertiesWindow.Show();
|
_propertiesWindow.Show();
|
||||||
_assetViewer.Show();
|
_assetViewer.Show();
|
||||||
_logWindow.Show();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,6 @@ namespace GlitchyEditor
|
|||||||
public this(String[] args)
|
public this(String[] args)
|
||||||
{
|
{
|
||||||
PushLayer(new EditorLayer(args, _contentManager));
|
PushLayer(new EditorLayer(args, _contentManager));
|
||||||
|
|
||||||
Log.ClientLogger = new EditorLogger();
|
|
||||||
Log.EngineLogger = new EditorLogger() { IsEngineLogger = true };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IContentManager InitContentManager()
|
protected override IContentManager InitContentManager()
|
||||||
|
|||||||
@@ -19,10 +19,6 @@ namespace GlitchyEditor
|
|||||||
public SubTexture2D Simulate ~ _.ReleaseRef();
|
public SubTexture2D Simulate ~ _.ReleaseRef();
|
||||||
public SubTexture2D Pause ~ _.ReleaseRef();
|
public SubTexture2D Pause ~ _.ReleaseRef();
|
||||||
public SubTexture2D SingleStep ~ _.ReleaseRef();
|
public SubTexture2D SingleStep ~ _.ReleaseRef();
|
||||||
public SubTexture2D Error ~ _.ReleaseRef();
|
|
||||||
public SubTexture2D Warning ~ _.ReleaseRef();
|
|
||||||
public SubTexture2D Info ~ _.ReleaseRef();
|
|
||||||
public SubTexture2D Trace ~ _.ReleaseRef();
|
|
||||||
|
|
||||||
public SamplerState SamplerState
|
public SamplerState SamplerState
|
||||||
{
|
{
|
||||||
@@ -45,10 +41,6 @@ namespace GlitchyEditor
|
|||||||
Simulate = GetNextGridTexture(ref pen, iconSize);
|
Simulate = GetNextGridTexture(ref pen, iconSize);
|
||||||
Pause = GetNextGridTexture(ref pen, iconSize);
|
Pause = GetNextGridTexture(ref pen, iconSize);
|
||||||
SingleStep = GetNextGridTexture(ref pen, iconSize);
|
SingleStep = GetNextGridTexture(ref pen, iconSize);
|
||||||
Error = GetNextGridTexture(ref pen, iconSize);
|
|
||||||
Warning = GetNextGridTexture(ref pen, iconSize);
|
|
||||||
Info = GetNextGridTexture(ref pen, iconSize);
|
|
||||||
Trace = GetNextGridTexture(ref pen, iconSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private SubTexture2D GetNextGridTexture(ref float2 pen, float2 iconSize)
|
private SubTexture2D GetNextGridTexture(ref float2 pen, float2 iconSize)
|
||||||
|
|||||||
@@ -171,11 +171,6 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
ContentBrowserWindow.s_FolderTexture = _editorIcons.Folder;
|
ContentBrowserWindow.s_FolderTexture = _editorIcons.Folder;
|
||||||
ContentBrowserWindow.s_FileTexture = _editorIcons.File;
|
ContentBrowserWindow.s_FileTexture = _editorIcons.File;
|
||||||
|
|
||||||
LogWindow.s_ErrorIcon = _editorIcons.Error;
|
|
||||||
LogWindow.s_WarningIcon = _editorIcons.Warning;
|
|
||||||
LogWindow.s_InfoIcon = _editorIcons.Info;
|
|
||||||
LogWindow.s_TraceIcon = _editorIcons.Trace;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitEditor()
|
private void InitEditor()
|
||||||
@@ -370,8 +365,17 @@ namespace GlitchyEditor
|
|||||||
dispatcher.Dispatch<MouseScrolledEvent>(scope (e) => OnMouseScrolled(e));
|
dispatcher.Dispatch<MouseScrolledEvent>(scope (e) => OnMouseScrolled(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui.ID _mainDockspaceId;
|
||||||
|
|
||||||
|
TextureViewer viewer = new TextureViewer() ~ delete _;
|
||||||
|
|
||||||
private bool OnImGuiRender(ImGuiRenderEvent event)
|
private bool OnImGuiRender(ImGuiRenderEvent event)
|
||||||
{
|
{
|
||||||
|
// TODO: make window
|
||||||
|
//Input.ImGuiDebugDraw();
|
||||||
|
|
||||||
|
//viewer.ViewTexture(Renderer.[Friend]_gBuffer.Target);
|
||||||
|
|
||||||
ImGui.Viewport* viewport = ImGui.GetMainViewport();
|
ImGui.Viewport* viewport = ImGui.GetMainViewport();
|
||||||
ImGui.DockSpaceOverViewport(viewport);
|
ImGui.DockSpaceOverViewport(viewport);
|
||||||
|
|
||||||
@@ -423,13 +427,9 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
ImGui.SetCursorPosX(centerX - totalWidth / 2);
|
ImGui.SetCursorPosX(centerX - totalWidth / 2);
|
||||||
|
|
||||||
ImGui.PushID(0);
|
|
||||||
|
|
||||||
if (ImGui.ImageButton("", _editorIcons.Play, .(size, size), .Zero, .Ones))
|
if (ImGui.ImageButton(_editorIcons.Play, .(size, size), .Zero, .Ones, 0))
|
||||||
OnScenePlay();
|
OnScenePlay();
|
||||||
|
|
||||||
ImGui.PopID();
|
|
||||||
|
|
||||||
ImGui.AttachTooltip("Play the game.");
|
ImGui.AttachTooltip("Play the game.");
|
||||||
|
|
||||||
@@ -437,7 +437,7 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
ImGui.PushID(1);
|
ImGui.PushID(1);
|
||||||
|
|
||||||
if (ImGui.ImageButton("", _editorIcons.Simulate, .(size, size), .Zero, .Ones))
|
if (ImGui.ImageButton(_editorIcons.Simulate, .(size, size), .Zero, .Ones, 0))
|
||||||
OnSceneSimulate();
|
OnSceneSimulate();
|
||||||
|
|
||||||
ImGui.PopID();
|
ImGui.PopID();
|
||||||
@@ -456,7 +456,7 @@ namespace GlitchyEditor
|
|||||||
//ImGui.SameLine(penX += size + 2 * padding);
|
//ImGui.SameLine(penX += size + 2 * padding);
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
|
|
||||||
if (ImGui.ImageButton("", _editorIcons.Pause, .(size, size), .Zero, .Ones))
|
if (ImGui.ImageButton(_editorIcons.Pause, .(size, size), .Zero, .Ones, 0))
|
||||||
_isPaused = !_isPaused;
|
_isPaused = !_isPaused;
|
||||||
|
|
||||||
ImGui.PopID();
|
ImGui.PopID();
|
||||||
@@ -480,7 +480,7 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
SubTexture2D pauseButtonIcon = _isPaused ? _editorIcons.Play : _editorIcons.Pause;
|
SubTexture2D pauseButtonIcon = _isPaused ? _editorIcons.Play : _editorIcons.Pause;
|
||||||
|
|
||||||
if (ImGui.ImageButton("PlayPause", pauseButtonIcon, .(size, size), .Zero, .Ones))
|
if (ImGui.ImageButton(pauseButtonIcon, .(size, size), .Zero, .Ones, 0))
|
||||||
{
|
{
|
||||||
if (_isPaused)
|
if (_isPaused)
|
||||||
OnSceneResume();
|
OnSceneResume();
|
||||||
@@ -498,7 +498,7 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
SubTexture2D singleStepButtonIcon = _editorIcons.SingleStep;
|
SubTexture2D singleStepButtonIcon = _editorIcons.SingleStep;
|
||||||
|
|
||||||
if (ImGui.ImageButton("Step", singleStepButtonIcon, .(size, size), .Zero, .Ones))
|
if (ImGui.ImageButton(singleStepButtonIcon, .(size, size), .Zero, .Ones, 0))
|
||||||
{
|
{
|
||||||
DoSingleStep();
|
DoSingleStep();
|
||||||
}
|
}
|
||||||
@@ -529,7 +529,7 @@ namespace GlitchyEditor
|
|||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
ImGui.PushID(1);
|
ImGui.PushID(1);
|
||||||
|
|
||||||
if (ImGui.ImageButton("Stop", _editorIcons.Stop, .(size, size), .Zero, .Ones))
|
if (ImGui.ImageButton(_editorIcons.Stop, .(size, size), .Zero, .Ones, 0))
|
||||||
OnSceneStop();
|
OnSceneStop();
|
||||||
|
|
||||||
ImGui.PopID();
|
ImGui.PopID();
|
||||||
@@ -807,9 +807,6 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
if(ImGui.MenuItem(AssetViewer.s_WindowTitle))
|
if(ImGui.MenuItem(AssetViewer.s_WindowTitle))
|
||||||
_editor.AssetViewer.Open = true;
|
_editor.AssetViewer.Open = true;
|
||||||
|
|
||||||
if(ImGui.MenuItem(LogWindow.s_WindowTitle))
|
|
||||||
_editor.LogWindow.Open = true;
|
|
||||||
|
|
||||||
ImGui.EndMenu();
|
ImGui.EndMenu();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,128 +0,0 @@
|
|||||||
using GlitchLog;
|
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using GlitchyEngine.Scripting;
|
|
||||||
|
|
||||||
namespace GlitchyEditor;
|
|
||||||
|
|
||||||
public class EditorLogger : Logger
|
|
||||||
{
|
|
||||||
// {l} = log level (first parameter)
|
|
||||||
// {t} = current date time (second parameter)
|
|
||||||
// {n} = logger name (third parameter)
|
|
||||||
// {m} = message
|
|
||||||
|
|
||||||
private String _name;
|
|
||||||
|
|
||||||
public override String Name
|
|
||||||
{
|
|
||||||
get => _name;
|
|
||||||
set => _name = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsEngineLogger {get; set;}
|
|
||||||
|
|
||||||
public this()
|
|
||||||
{
|
|
||||||
//Debug.Assert(Debug.IsDebuggerPresent, "The DebugLogger requires a debugger to be present.");
|
|
||||||
}
|
|
||||||
|
|
||||||
#if GL_NOLOG || GL_LOG_NOTRACE
|
|
||||||
[SkipCall]
|
|
||||||
#endif
|
|
||||||
[Inline]
|
|
||||||
public override void Trace(StringView format, params Object[] args)
|
|
||||||
{
|
|
||||||
InternalLog(.Trace, format, params args);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if GL_NOLOG || GL_LOG_NOINFO
|
|
||||||
[SkipCall]
|
|
||||||
#endif
|
|
||||||
[Inline]
|
|
||||||
public override void Info(StringView format, params Object[] args)
|
|
||||||
{
|
|
||||||
InternalLog(.Info, format, params args);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if GL_NOLOG || GL_LOG_NOWARNING
|
|
||||||
[SkipCall]
|
|
||||||
#endif
|
|
||||||
[Inline]
|
|
||||||
public override void Warning(StringView format, params Object[] args)
|
|
||||||
{
|
|
||||||
InternalLog(.Warning, format, params args);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if GL_NOLOG || GL_LOG_NOERROR
|
|
||||||
[SkipCall]
|
|
||||||
#endif
|
|
||||||
[Inline]
|
|
||||||
public override void Error(StringView format, params Object[] args)
|
|
||||||
{
|
|
||||||
InternalLog(.Error, format, params args);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if GL_NOLOG || GL_LOG_NOCRITICAL
|
|
||||||
[SkipCall]
|
|
||||||
#endif
|
|
||||||
[Inline]
|
|
||||||
public override void Critical(StringView format, params Object[] args)
|
|
||||||
{
|
|
||||||
InternalLog(.Critical, format, params args);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if GL_NOLOG
|
|
||||||
[SkipCall]
|
|
||||||
#endif
|
|
||||||
[Inline]
|
|
||||||
public override void Log(LogLevel level, StringView format, params Object[] args)
|
|
||||||
{
|
|
||||||
InternalLog(level, format, params args);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Assert(bool condition, String error = Compiler.CallerExpression[0], String filePath = Compiler.CallerFilePath, int line = Compiler.CallerLineNum)
|
|
||||||
{
|
|
||||||
if (!condition)
|
|
||||||
{
|
|
||||||
String failStr = scope .()..AppendF("Assert failed: {} at line {} in {}", error, line, filePath);
|
|
||||||
InternalLog(.Critical, failStr);
|
|
||||||
Internal.FatalError(failStr, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void AssertDebug(bool condition, String error = Compiler.CallerExpression[0], String filePath = Compiler.CallerFilePath, int line = Compiler.CallerLineNum)
|
|
||||||
{
|
|
||||||
if (!condition)
|
|
||||||
{
|
|
||||||
String failStr = scope .()..AppendF("Assert failed: {} at line {} in {}", error, line, filePath);
|
|
||||||
InternalLog(.Critical, failStr);
|
|
||||||
Internal.FatalError(failStr, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InternalLog(LogLevel level, StringView format, params Object[] args)
|
|
||||||
{
|
|
||||||
if(_logLevel > level)
|
|
||||||
return;
|
|
||||||
|
|
||||||
DateTime timestamp = DateTime.Now;
|
|
||||||
|
|
||||||
String message = scope String(4096);
|
|
||||||
message.AppendF(format, params args);
|
|
||||||
|
|
||||||
Debug.Write($"[{timestamp:HH:mm:ss.fff}] ({_name})|{level.UpperString}: {message}");
|
|
||||||
|
|
||||||
if (Editor.Instance == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (args.Count > 0 && (var ex = args[^1] as MonoExceptionHelper))
|
|
||||||
{
|
|
||||||
Editor.Instance.LogWindow.LogException(timestamp, ex);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Editor.Instance.LogWindow.Log(timestamp, level, message, new .() {IsEngineMessage = IsEngineLogger});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace ImGui;
|
|
||||||
|
|
||||||
enum DragDropPayloadType
|
|
||||||
{
|
|
||||||
case ContentBrowserItem;
|
|
||||||
case Entity;
|
|
||||||
|
|
||||||
public String GetName()
|
|
||||||
{
|
|
||||||
switch (this)
|
|
||||||
{
|
|
||||||
case .ContentBrowserItem:
|
|
||||||
return "CONTENT_BROWSER_ITEM";
|
|
||||||
case .Entity:
|
|
||||||
return "ENTITY";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension ImGui
|
|
||||||
{
|
|
||||||
public static Payload* AcceptDragDropPayload(DragDropPayloadType type, DragDropFlags flags = .None)
|
|
||||||
{
|
|
||||||
return AcceptDragDropPayload(type.GetName(), flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool SetDragDropPayload(DragDropPayloadType type, void* data, size sz, Cond cond = .None)
|
|
||||||
{
|
|
||||||
return SetDragDropPayload(type.GetName(), data, sz, cond);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,247 @@
|
|||||||
|
using GlitchyEngine.Renderer;
|
||||||
|
using GlitchyEngine;
|
||||||
|
using ImGui;
|
||||||
|
using GlitchyEngine.Math;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace GlitchyEditor
|
||||||
|
{
|
||||||
|
class TextureViewer
|
||||||
|
{
|
||||||
|
enum BackgroundMode : int32
|
||||||
|
{
|
||||||
|
White,
|
||||||
|
Black,
|
||||||
|
Checkerboard
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SampleMode : int32
|
||||||
|
{
|
||||||
|
Point,
|
||||||
|
Linear
|
||||||
|
}
|
||||||
|
|
||||||
|
GraphicsContext _context ~ _.ReleaseRef();
|
||||||
|
|
||||||
|
Effect _effect ~ _.ReleaseRef();
|
||||||
|
|
||||||
|
float _zoom = 1.0f;
|
||||||
|
|
||||||
|
BackgroundMode _backgroundMode = .Checkerboard;
|
||||||
|
|
||||||
|
SampleMode _sampleMode = .Linear;
|
||||||
|
|
||||||
|
RenderTarget2D _target ~ _?.ReleaseRef();
|
||||||
|
// TODO: we don't need depth!
|
||||||
|
DepthStencilTarget _depth ~ _?.ReleaseRef();
|
||||||
|
|
||||||
|
SamplerState _samplerPoint ~ _.ReleaseRef();
|
||||||
|
SamplerState _samplerLinear ~ _.ReleaseRef();
|
||||||
|
|
||||||
|
public this()
|
||||||
|
{
|
||||||
|
_context = Application.Get().Window.Context..AddRef();
|
||||||
|
|
||||||
|
InitEffect();
|
||||||
|
InitState();
|
||||||
|
// TODO: rasterizerstate and depthstencilstate
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitEffect()
|
||||||
|
{
|
||||||
|
_effect = new Effect("content\\Shaders\\textureViewerShader.hlsl");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitState()
|
||||||
|
{
|
||||||
|
SamplerStateDescription desc = .();
|
||||||
|
desc.MagFilter = .Linear;
|
||||||
|
desc.MinFilter = .Linear;
|
||||||
|
_samplerLinear = SamplerStateManager.GetSampler(desc);
|
||||||
|
|
||||||
|
desc.MagFilter = .Point;
|
||||||
|
desc.MinFilter = .Point;
|
||||||
|
_samplerPoint = SamplerStateManager.GetSampler(desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
float2 _position;
|
||||||
|
|
||||||
|
bool _moving;
|
||||||
|
|
||||||
|
float _colorOffset = 0;
|
||||||
|
float _colorScale = 1;
|
||||||
|
float _alphaOffset = 0;
|
||||||
|
float _alphaScale = 1;
|
||||||
|
|
||||||
|
public void ViewTexture(Texture viewedTexture)
|
||||||
|
{
|
||||||
|
ImGui.Begin("Texture Viewer");
|
||||||
|
|
||||||
|
ImGui.SliderFloat("Zoom", &_zoom, 0.01f, 100.0f);
|
||||||
|
|
||||||
|
char8*[] items = scope .("White", "Black", "Checkerboard");
|
||||||
|
|
||||||
|
ImGui.Combo("Background", (.)&_backgroundMode, items.Ptr, (.)items.Count);
|
||||||
|
|
||||||
|
items = scope .("Point", "Linear");
|
||||||
|
|
||||||
|
ImGui.Combo("Sampler", (.)&_sampleMode, items.Ptr, (.)items.Count);
|
||||||
|
|
||||||
|
ImGui.SliderFloat2("Color offset and scale", *(float[2]*)&_colorOffset, -1.0f, 1.0f);
|
||||||
|
ImGui.SliderFloat2("Alpha offset and scale", *(float[2]*)&_alphaOffset, -1.0f, 1.0f);
|
||||||
|
|
||||||
|
ImGui.SliderFloat2("Position", *(float[2]*)&_position, 2 * -Math.Max(viewedTexture.Width, viewedTexture.Height) * _zoom, 2 * Math.Max(viewedTexture.Width, viewedTexture.Height) * _zoom);
|
||||||
|
|
||||||
|
ImGui.BeginChild("imageChild");
|
||||||
|
|
||||||
|
UpdateInput();
|
||||||
|
|
||||||
|
var viewportSize = ImGui.GetContentRegionAvail();
|
||||||
|
|
||||||
|
viewportSize.x = Math.Max(viewportSize.x, 1);
|
||||||
|
viewportSize.y = Math.Max(viewportSize.y, 1);
|
||||||
|
|
||||||
|
if(_target == null || viewportSize.x != _target.Width || viewportSize.y != _target.Height)
|
||||||
|
{
|
||||||
|
_target?.ReleaseRef();
|
||||||
|
_target = new RenderTarget2D(.(.R8G8B8A8_UNorm, (.)viewportSize.x, (.)viewportSize.y));
|
||||||
|
_target.SamplerState = SamplerStateManager.PointClamp;
|
||||||
|
_depth?.ReleaseRef();
|
||||||
|
_depth = new DepthStencilTarget((.)viewportSize.x, (.)viewportSize.y, .D16_UNorm);
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderTexture(viewedTexture);
|
||||||
|
|
||||||
|
ImGui.Image(_target, viewportSize);
|
||||||
|
|
||||||
|
ImGui.EndChild();
|
||||||
|
|
||||||
|
ImGui.End();
|
||||||
|
}
|
||||||
|
|
||||||
|
float lastWheel;
|
||||||
|
|
||||||
|
private void UpdateInput()
|
||||||
|
{
|
||||||
|
var windowPos = ImGui.GetWindowPos();
|
||||||
|
var mousePos = ImGui.GetIO().MousePos;
|
||||||
|
float2 mouseInWindow = .(mousePos.x - windowPos.x, mousePos.y - windowPos.y);
|
||||||
|
|
||||||
|
bool windowHovered = ImGui.IsWindowHovered();
|
||||||
|
|
||||||
|
if(windowHovered && Input.IsMouseButtonPressing(.MiddleButton))
|
||||||
|
{
|
||||||
|
_moving = true;
|
||||||
|
}
|
||||||
|
else if(Input.IsMouseButtonReleased(.MiddleButton))
|
||||||
|
{
|
||||||
|
_moving = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(windowHovered || _moving)
|
||||||
|
{
|
||||||
|
float mouseWheel = ImGui.GetIO().MouseWheel;
|
||||||
|
|
||||||
|
float delta = mouseWheel - lastWheel;
|
||||||
|
|
||||||
|
if(delta != 0)
|
||||||
|
{
|
||||||
|
_position -= mouseInWindow;
|
||||||
|
_position /= _zoom;
|
||||||
|
|
||||||
|
_zoom *= Math.Pow(1.1f, delta);
|
||||||
|
|
||||||
|
_position *= _zoom;
|
||||||
|
_position += mouseInWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_moving)
|
||||||
|
{
|
||||||
|
int2 movement = Input.GetMouseMovement();
|
||||||
|
|
||||||
|
_position.X += movement.X;
|
||||||
|
_position.Y += movement.Y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OrthographicCamera _camera = new OrthographicCamera() ~ delete _;
|
||||||
|
|
||||||
|
private void RenderTexture(Texture viewedTexture)
|
||||||
|
{
|
||||||
|
Viewport vp = .(0, 0, _target.Width, _target.Height);
|
||||||
|
RenderCommand.SetViewport(vp);
|
||||||
|
|
||||||
|
// TODO: don't clear pink!
|
||||||
|
RenderCommand.Clear(_target, .Pink);
|
||||||
|
RenderCommand.Clear(_depth, .Depth, 1.0f, 0);
|
||||||
|
|
||||||
|
//_target.Bind();
|
||||||
|
_context.SetRenderTarget(_target);
|
||||||
|
_context.SetDepthStencilTarget(_depth);
|
||||||
|
_context.BindRenderTargets();
|
||||||
|
|
||||||
|
float2 textureSize = float2(viewedTexture.Width, viewedTexture.Height);
|
||||||
|
float2 zoomedTextureSize = textureSize * _zoom;
|
||||||
|
|
||||||
|
float2 targetSize = float2(_target.Width, _target.Height);
|
||||||
|
|
||||||
|
_effect.Variables["ColorOffset"].SetData(_colorOffset);
|
||||||
|
_effect.Variables["ColorScale"].SetData(_colorScale);
|
||||||
|
_effect.Variables["AlphaOffset"].SetData(_alphaOffset);
|
||||||
|
_effect.Variables["AlphaScale"].SetData(_alphaScale);
|
||||||
|
|
||||||
|
_camera.Left = 0;
|
||||||
|
_camera.Top = 0;
|
||||||
|
_camera.Right = targetSize.X;
|
||||||
|
_camera.Bottom = -targetSize.Y;
|
||||||
|
_camera.NearPlane = -5;
|
||||||
|
_camera.FarPlane = 5;
|
||||||
|
_camera.Update();
|
||||||
|
|
||||||
|
Renderer2D.BeginScene(_camera);
|
||||||
|
|
||||||
|
switch(_backgroundMode)
|
||||||
|
{
|
||||||
|
case .Black:
|
||||||
|
Renderer2D.DrawQuadPivotCorner(float3(0, 0, 1), targetSize, 0, .Black);
|
||||||
|
case .White:
|
||||||
|
Renderer2D.DrawQuadPivotCorner(float3(0, 0, 1), targetSize, 0, .White);
|
||||||
|
case .Checkerboard:
|
||||||
|
float quadSize = 50.0f;
|
||||||
|
|
||||||
|
float2 numQuads = (targetSize / 500f) * 10f;
|
||||||
|
|
||||||
|
for(float x = 0; x < numQuads.X; x++)
|
||||||
|
{
|
||||||
|
for(float y = 0; y < numQuads.Y; y++)
|
||||||
|
{
|
||||||
|
Renderer2D.DrawQuadPivotCorner(float3(x * quadSize, -y * quadSize, 1), quadSize.XX, 0, ((x + y) % 2 == 0) ? .White : .Gray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Renderer2D.EndScene();
|
||||||
|
|
||||||
|
var sampler = viewedTexture.SamplerState;
|
||||||
|
|
||||||
|
switch(_sampleMode)
|
||||||
|
{
|
||||||
|
case .Point:
|
||||||
|
viewedTexture.SamplerState = _samplerPoint;
|
||||||
|
case .Linear:
|
||||||
|
viewedTexture.SamplerState = _samplerLinear;
|
||||||
|
}
|
||||||
|
|
||||||
|
Renderer2D.BeginScene(_camera, .SortByTexture, _effect);
|
||||||
|
|
||||||
|
Renderer2D.DrawQuad(float3(_position * .(1, -1), 0), zoomedTextureSize, 0, viewedTexture);
|
||||||
|
|
||||||
|
Renderer2D.EndScene();
|
||||||
|
|
||||||
|
viewedTexture.SamplerState = sampler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
FileVersion = 1
|
FileVersion = 1
|
||||||
Dependencies = {GlitchLog = "*", corlib = "*", DirectX = "*", FreeType = "*", cgltf-beef = "*", msdfgen-beef = "*", ImGui = "*", ImGuiImplDX11 = "*", ImGuiImplWin32 = "*", ImGuizmo = "*", Beefy2D = "*", LodePng = "*", GlitchyEngineHelper = "*", bon = "*", box2d-beef = "*", "Beef.Linq" = "*"}
|
Dependencies = {GlitchLog = "*", corlib = "*", DirectX = "*", FreeType = "*", cgltf-beef = "*", msdfgen-beef = "*", ImGui = "*", ImGuiImplDX11 = "*", ImGuiImplWin32 = "*", ImGuizmo = "*", Beefy2D = "*", LodePng = "*", GlitchyEngineHelper = "*", bon = "*", box2d-beef = "*", "Beef.Linq" = "*", NetHostBeef = "*"}
|
||||||
|
|
||||||
[Project]
|
[Project]
|
||||||
Name = "GlitchyEngine"
|
Name = "GlitchyEngine"
|
||||||
|
|||||||
@@ -71,23 +71,26 @@ namespace GlitchyEngine
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static mixin ClearDictionaryAndReleaseKeys(var dictionary)
|
public static mixin ClearDictionaryAndDeleteValues(var dictionary)
|
||||||
{
|
{
|
||||||
if (dictionary != null)
|
if (dictionary != null)
|
||||||
{
|
{
|
||||||
for (var value in dictionary)
|
for (var value in dictionary)
|
||||||
value.key?.ReleaseRef();
|
delete value.value;
|
||||||
dictionary.Clear();
|
delete dictionary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static mixin ClearDictionaryAndReleaseValues(var dictionary)
|
public static mixin ClearDictionaryAndDeleteKeysAndValues(var dictionary)
|
||||||
{
|
{
|
||||||
if (dictionary != null)
|
if (dictionary != null)
|
||||||
{
|
{
|
||||||
for (var value in dictionary)
|
for (var value in dictionary)
|
||||||
value.value?.ReleaseRef();
|
{
|
||||||
dictionary.Clear();
|
delete value.key;
|
||||||
|
delete value.value;
|
||||||
|
}
|
||||||
|
delete dictionary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,30 +87,18 @@ namespace ImGui
|
|||||||
|
|
||||||
public static extern void Image(TextureViewBinding textureViewBinding, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, Vec4 tint_col = Vec4.Ones, Vec4 border_col = Vec4.Zero);
|
public static extern void Image(TextureViewBinding textureViewBinding, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, Vec4 tint_col = Vec4.Ones, Vec4 border_col = Vec4.Zero);
|
||||||
|
|
||||||
public static bool ImageButton(char8* id, SubTexture2D subTexture, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, Vec4 bg_col = Vec4.Zero, Vec4 tint_col = Vec4.Ones)
|
public static bool ImageButton(SubTexture2D subTexture, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, int32 frame_padding = -1, Vec4 bg_col = Vec4.Zero, Vec4 tint_col = Vec4.Ones)
|
||||||
{
|
{
|
||||||
if (uv0 != .Zero || uv1 != .Ones)
|
if (uv0 != .Zero || uv1 != .Ones)
|
||||||
Runtime.NotImplemented();
|
Runtime.NotImplemented();
|
||||||
|
|
||||||
float2 v = (.)subTexture.TexCoords.XY + subTexture.TexCoords.ZW;
|
float2 v = (.)subTexture.TexCoords.XY + subTexture.TexCoords.ZW;
|
||||||
|
|
||||||
return ImageButton(id, subTexture.Texture.GetViewBinding(), size, (.)subTexture.TexCoords.XY, (.)v, bg_col, tint_col);
|
return ImageButton(subTexture.Texture.GetViewBinding(), size, (.)subTexture.TexCoords.XY, (.)v, frame_padding, bg_col, tint_col);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static extern bool ImageButton(char8* id, TextureViewBinding textureViewBinding, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, Vec4 bg_col = Vec4.Zero, Vec4 tint_col = Vec4.Ones);
|
public static extern bool ImageButton(TextureViewBinding textureViewBinding, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, int32 frame_padding = -1, Vec4 bg_col = Vec4.Zero, Vec4 tint_col = Vec4.Ones);
|
||||||
|
|
||||||
public static bool ImageButtonEx(uint32 id, SubTexture2D subTexture, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, Vec4 bg_col = Vec4.Zero, Vec4 tint_col = Vec4.Ones)
|
|
||||||
{
|
|
||||||
if (uv0 != .Zero || uv1 != .Ones)
|
|
||||||
Runtime.NotImplemented();
|
|
||||||
|
|
||||||
float2 v = (.)subTexture.TexCoords.XY + subTexture.TexCoords.ZW;
|
|
||||||
|
|
||||||
return ImageButtonEx(id, subTexture.Texture.GetViewBinding(), size, (.)subTexture.TexCoords.XY, (.)v, bg_col, tint_col);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static extern bool ImageButtonEx(uint32 id, TextureViewBinding textureViewBinding, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, Vec4 bg_col = Vec4.Zero, Vec4 tint_col = Vec4.Ones);
|
|
||||||
|
|
||||||
public static void TextUnformatted(StringView text) => TextUnformattedImpl(text.Ptr, text.Ptr + text.Length);
|
public static void TextUnformatted(StringView text) => TextUnformattedImpl(text.Ptr, text.Ptr + text.Length);
|
||||||
|
|
||||||
public static void PushID(StringView id) => PushID(id.Ptr, id.Ptr + id.Length);
|
public static void PushID(StringView id) => PushID(id.Ptr, id.Ptr + id.Length);
|
||||||
|
|||||||
@@ -86,42 +86,29 @@ namespace GlitchyEngine.ImGui
|
|||||||
ImGuizmo.BeginFrame();
|
ImGuizmo.BeginFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadFont()
|
|
||||||
{
|
|
||||||
var settings = Application.Instance.Settings.ImGuiSettings;
|
|
||||||
|
|
||||||
ImGui.GetIO().Fonts.Clear();
|
|
||||||
|
|
||||||
Stream fontFile = Application.Instance.ContentManager.GetStream(settings.FontName);
|
|
||||||
|
|
||||||
if (fontFile != null)
|
|
||||||
{
|
|
||||||
// We need to use ImGuis memory allocator because ImGui takes ownership
|
|
||||||
uint8* fontData = (uint8*)ImGui.MemAlloc((uint64)fontFile.Length);
|
|
||||||
var result = fontFile.TryRead(Span<uint8>(fontData, fontFile.Length));
|
|
||||||
|
|
||||||
if (result case .Err)
|
|
||||||
Log.EngineLogger.Error($"Failed to load font \"{settings.FontName}\" from stream.");
|
|
||||||
|
|
||||||
ImGui.GetIO().Fonts.AddFontFromMemoryTTF(fontData, (int32)fontFile.Length, settings.FontSize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ImGui.GetIO().Fonts.AddFontDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.GetIO().Fonts.AddFontDefault();
|
|
||||||
|
|
||||||
delete fontFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ImGuiRender()
|
public void ImGuiRender()
|
||||||
{
|
{
|
||||||
Debug.Profiler.ProfileFunction!();
|
Debug.Profiler.ProfileFunction!();
|
||||||
|
|
||||||
if (SettingsInvalid)
|
if (SettingsInvalid)
|
||||||
{
|
{
|
||||||
LoadFont();
|
var settings = Application.Get().Settings.ImGuiSettings;
|
||||||
|
|
||||||
|
ImGui.GetIO().Fonts.Clear();
|
||||||
|
|
||||||
|
// TODO: Fix fonts
|
||||||
|
//String fullpath = scope String();
|
||||||
|
//Application.Get().ContentManager.GetFilePath(fullpath, settings.FontName);
|
||||||
|
/*Application.Get().ContentManager.GetStream(settings.FontName);
|
||||||
|
if (File.Exists(fullpath))
|
||||||
|
{
|
||||||
|
ImGui.GetIO().Fonts.AddFontFromMemoryTTF();
|
||||||
|
ImGui.GetIO().Fonts.AddFontFromFileTTF(fullpath, settings.FontSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{*/
|
||||||
|
ImGui.GetIO().Fonts.AddFontDefault();
|
||||||
|
//}
|
||||||
|
|
||||||
#if GE_GRAPHICS_DX11
|
#if GE_GRAPHICS_DX11
|
||||||
ImGuiImplDX11.CreateDeviceObjects();
|
ImGuiImplDX11.CreateDeviceObjects();
|
||||||
|
|||||||
@@ -8,33 +8,10 @@ namespace GlitchyEngine
|
|||||||
static Logger _engineLogger ~ delete _;
|
static Logger _engineLogger ~ delete _;
|
||||||
static Logger _clientLogger ~ delete _;
|
static Logger _clientLogger ~ delete _;
|
||||||
|
|
||||||
public static Logger EngineLogger
|
[Inline]
|
||||||
{
|
public static Logger EngineLogger => _engineLogger;
|
||||||
[Inline]
|
[Inline]
|
||||||
get => _engineLogger;
|
public static Logger ClientLogger => _clientLogger;
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_engineLogger == value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
delete _engineLogger;
|
|
||||||
_engineLogger = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Logger ClientLogger
|
|
||||||
{
|
|
||||||
[Inline]
|
|
||||||
get => _clientLogger;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_clientLogger == value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
delete _clientLogger;
|
|
||||||
_clientLogger = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static this()
|
static this()
|
||||||
{
|
{
|
||||||
|
|||||||
+2
-14
@@ -22,24 +22,12 @@ namespace ImGui
|
|||||||
textureViewBinding.Release();
|
textureViewBinding.Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static override bool ImageButton(char8* id, TextureViewBinding textureViewBinding, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, Vec4 bg_col = Vec4.Zero, Vec4 tint_col = Vec4.Ones)
|
public static override bool ImageButton(TextureViewBinding textureViewBinding, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, int32 frame_padding = -1, Vec4 bg_col = Vec4.Zero, Vec4 tint_col = Vec4.Ones)
|
||||||
{
|
{
|
||||||
var view = textureViewBinding._nativeShaderResourceView..AddRef();
|
var view = textureViewBinding._nativeShaderResourceView..AddRef();
|
||||||
_resourceViews.Add(view);
|
_resourceViews.Add(view);
|
||||||
|
|
||||||
bool pressed = ImGui.ImageButton(id, view, size, uv0, uv1, bg_col, tint_col);
|
bool pressed = ImGui.ImageButton(view, size, uv0, uv1, frame_padding, bg_col, tint_col);
|
||||||
|
|
||||||
textureViewBinding.Release();
|
|
||||||
|
|
||||||
return pressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static override bool ImageButtonEx(uint32 id, TextureViewBinding textureViewBinding, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, Vec4 bg_col = Vec4.Zero, Vec4 tint_col = Vec4.Ones)
|
|
||||||
{
|
|
||||||
var view = textureViewBinding._nativeShaderResourceView..AddRef();
|
|
||||||
_resourceViews.Add(view);
|
|
||||||
|
|
||||||
bool pressed = ImGui.ImageButtonEx(id, view, size, uv0, uv1, bg_col, tint_col);
|
|
||||||
|
|
||||||
textureViewBinding.Release();
|
textureViewBinding.Release();
|
||||||
|
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
using NetHostBeef;
|
||||||
|
using System;
|
||||||
|
using System.Interop;
|
||||||
|
using GlitchyEngine.Core;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Scripting;
|
||||||
|
|
||||||
|
static class CoreClrHelper
|
||||||
|
{
|
||||||
|
static HostFxr.InitializeForDotnetCommandLineFn HostFxr_Init;
|
||||||
|
static HostFxr.GetRuntimeDelegateFn HostFxr_GetDelegate;
|
||||||
|
static HostFxr.CloseFn HostFxr_Close;
|
||||||
|
|
||||||
|
static CoreClr.LoadAssemblyAndGetFunctionPointerFn LoadAssemblyAndGetFunctionPointerFn;
|
||||||
|
static CoreClr.GetFunctionPointerFn GetFunctionPointerFn;
|
||||||
|
|
||||||
|
private function void LoadScriptAssemblyFunc(uint8* appData, int64 appLength, uint8* pdbData, int64 pdbLength);
|
||||||
|
|
||||||
|
//static function void(char8* path) LoadScriptAssembly;
|
||||||
|
static LoadScriptAssemblyFunc _loadScriptAssembly;
|
||||||
|
static function void() _unloadAssemblies;
|
||||||
|
|
||||||
|
// public static unsafe void GetScriptClasses(void** outBuffer, long* length)
|
||||||
|
private function void GetScriptClassesFunc(void** outBuffer, int64* length);
|
||||||
|
static GetScriptClassesFunc _getScriptClasses;
|
||||||
|
static function void() _freeScriptClassNames;
|
||||||
|
|
||||||
|
//public static unsafe ScriptFunctions CreateScriptInstance(UUID entityId, byte* scriptClassName)
|
||||||
|
private function ScriptFunctionPointers CreateScriptInstanceFunc(UUID entityId, char8* scriptClassName);
|
||||||
|
static CreateScriptInstanceFunc _createScriptInstance;
|
||||||
|
|
||||||
|
public static void Init(StringView coreAssemblyPath)
|
||||||
|
{
|
||||||
|
LoadHostFxr();
|
||||||
|
InitAndStartRuntime(coreAssemblyPath);
|
||||||
|
|
||||||
|
PrepareFunction();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LoadHostFxr()
|
||||||
|
{
|
||||||
|
char_t[256] buffer = ?;
|
||||||
|
c_size bufferSize = buffer.Count;
|
||||||
|
int rc = NetHost.get_hostfxr_path(&buffer, &bufferSize, null);
|
||||||
|
|
||||||
|
Log.EngineLogger.AssertDebug(rc == 0, "Failed to get HostFxr path.");
|
||||||
|
|
||||||
|
// Load hostfxr and get desired exports
|
||||||
|
void* lib = NetHostHelper.LoadLibrary(&buffer);
|
||||||
|
HostFxr_Init = NetHostHelper.GetExport<HostFxr.InitializeForDotnetCommandLineFn>(lib, "hostfxr_initialize_for_dotnet_command_line");
|
||||||
|
HostFxr_GetDelegate = NetHostHelper.GetExport<HostFxr.GetRuntimeDelegateFn>(lib, "hostfxr_get_runtime_delegate");
|
||||||
|
HostFxr_Close = NetHostHelper.GetExport<HostFxr.CloseFn>(lib, "hostfxr_close");
|
||||||
|
|
||||||
|
Log.EngineLogger.AssertDebug(HostFxr_Init != null && HostFxr_GetDelegate != null && HostFxr_Close != null, "Retrieving at least one HostFxr function failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void InitAndStartRuntime(StringView coreAssembly)
|
||||||
|
{
|
||||||
|
char_t* ptr = NetHostHelper.GetScopedRawPtr!(coreAssembly);
|
||||||
|
|
||||||
|
char_t*[2] args = char_t*[](
|
||||||
|
ptr,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
HostFxr.Handle cxt = null;
|
||||||
|
int rc = HostFxr_Init(1, &args, null, &cxt);
|
||||||
|
|
||||||
|
if (rc != 0 || cxt == null)
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Error($"Failed to initialize HostFxr: {rc}");
|
||||||
|
HostFxr_Close(cxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.EngineLogger.Assert(rc == 0, "Failed to initialize HostFxr.");
|
||||||
|
|
||||||
|
rc = HostFxr_GetDelegate(cxt, .LoadAssemblyAndGetFunctionPointer, (void**)&LoadAssemblyAndGetFunctionPointerFn);
|
||||||
|
|
||||||
|
Log.EngineLogger.Assert(rc == 0, scope $"Get delegate failed: {rc}. (LoadAssemblyAndGetFunctionPointer)");
|
||||||
|
|
||||||
|
rc = HostFxr_GetDelegate(cxt, .GetFunctionPointer, (void**)&GetFunctionPointerFn);
|
||||||
|
|
||||||
|
Log.EngineLogger.Assert(rc == 0, scope $"Get delegate failed: {rc}. (GetFunctionPointer)");
|
||||||
|
|
||||||
|
HostFxr_Close(cxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PrepareFunction()
|
||||||
|
{
|
||||||
|
GetFunctionPointerUnmanagedCallersOnly("GlitchyEngine.ScriptGlue, ScriptCore", "LoadScriptAssembly", out _loadScriptAssembly);
|
||||||
|
|
||||||
|
GetFunctionPointerUnmanagedCallersOnly("GlitchyEngine.ScriptGlue, ScriptCore", "UnloadAssemblies", out _unloadAssemblies);
|
||||||
|
|
||||||
|
GetFunctionPointerUnmanagedCallersOnly("GlitchyEngine.ScriptGlue, ScriptCore", "GetScriptClasses", out _getScriptClasses);
|
||||||
|
|
||||||
|
GetFunctionPointerUnmanagedCallersOnly("GlitchyEngine.ScriptGlue, ScriptCore", "FreeScriptClassNames", out _freeScriptClassNames);
|
||||||
|
|
||||||
|
GetFunctionPointerUnmanagedCallersOnly("GlitchyEngine.ScriptGlue, ScriptCore", "CreateScriptInstance", out _createScriptInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void LoadAppAssembly(Span<uint8> appAssemblyData, Span<uint8> pdbData)
|
||||||
|
{
|
||||||
|
_loadScriptAssembly(appAssemblyData.Ptr, appAssemblyData.Length, pdbData.Ptr, pdbData.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UnloadAssemblies()
|
||||||
|
{
|
||||||
|
_unloadAssemblies();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets an array of script class infos. Use FreeScriptClassNames to release the buffer.
|
||||||
|
public static void GetScriptClasses(out void* outBuffer, out int64 entryCount)
|
||||||
|
{
|
||||||
|
outBuffer = null;
|
||||||
|
entryCount = 0;
|
||||||
|
_getScriptClasses(&outBuffer, &entryCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Releases the buffer created by GetScriptClasses
|
||||||
|
public static void FreeScriptClassNames()
|
||||||
|
{
|
||||||
|
_freeScriptClassNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ScriptFunctionPointers CreateScriptInstance(UUID entityId, StringView scriptName)
|
||||||
|
{
|
||||||
|
return _createScriptInstance(entityId, scriptName.Ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetFunctionPointer<T>(StringView typeName, StringView methodName, StringView delegateName, out T outDelegate) where T: operator explicit void*
|
||||||
|
{
|
||||||
|
void* funPtr = null;
|
||||||
|
|
||||||
|
int rc = GetFunctionPointerFn(NetHostHelper.GetScopedRawPtr!(typeName),
|
||||||
|
NetHostHelper.GetScopedRawPtr!(methodName), NetHostHelper.GetScopedRawPtr!(delegateName),
|
||||||
|
null, null, out funPtr);
|
||||||
|
|
||||||
|
outDelegate = (T)funPtr;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetFunctionPointerDefaultDelegate(StringView typeName, StringView methodName, out CoreClr.DefaultEntryPoint outDelegate)
|
||||||
|
{
|
||||||
|
void* funPtr = null;
|
||||||
|
|
||||||
|
int rc = GetFunctionPointerFn(NetHostHelper.GetScopedRawPtr!(typeName),
|
||||||
|
NetHostHelper.GetScopedRawPtr!(methodName), null, null, null, out funPtr);
|
||||||
|
|
||||||
|
outDelegate = (CoreClr.DefaultEntryPoint)funPtr;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetFunctionPointerUnmanagedCallersOnly<T>(StringView typeName, StringView methodName, out T outDelegate) where T: operator explicit void*
|
||||||
|
{
|
||||||
|
void* funPtr = null;
|
||||||
|
|
||||||
|
int rc = GetFunctionPointerFn(NetHostHelper.GetScopedRawPtr!(typeName),
|
||||||
|
NetHostHelper.GetScopedRawPtr!(methodName), CoreClr.UNMANAGEDCALLERSONLY_METHOD, null, null, out funPtr);
|
||||||
|
|
||||||
|
outDelegate = (T)funPtr;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
using System;
|
|
||||||
using GlitchyEngine.Core;
|
|
||||||
using Mono;
|
|
||||||
|
|
||||||
namespace GlitchyEngine.Scripting;
|
|
||||||
|
|
||||||
|
|
||||||
public class MonoExceptionHelper : RefCounter
|
|
||||||
{
|
|
||||||
private String _fullName ~ delete _;
|
|
||||||
|
|
||||||
private String _message ~ delete _;
|
|
||||||
|
|
||||||
private String _stackTrace ~ delete _;
|
|
||||||
/// The clean stack trace only contains the Managed Stack (the full trace contains one line for the native-to-managed entry)
|
|
||||||
private StringView _cleanStackTrace;
|
|
||||||
|
|
||||||
private MonoExceptionHelper _innerException ~ _?.ReleaseRef();
|
|
||||||
|
|
||||||
public StringView FullName => _fullName;
|
|
||||||
public StringView Message => _message;
|
|
||||||
|
|
||||||
public StringView StackTrace => _stackTrace;
|
|
||||||
public StringView CleanStackTrace => _cleanStackTrace;
|
|
||||||
|
|
||||||
public MonoExceptionHelper InnerException => _innerException;
|
|
||||||
|
|
||||||
public UUID Instance { get; set; }
|
|
||||||
|
|
||||||
public this(MonoException* exception)
|
|
||||||
{
|
|
||||||
MonoObject* exObject = (MonoObject*)exception;
|
|
||||||
|
|
||||||
MonoClass* monoClass = Mono.mono_object_get_class(exObject);
|
|
||||||
|
|
||||||
StringView classNamespace = .(Mono.mono_class_get_namespace(monoClass));
|
|
||||||
StringView className = .(Mono.mono_class_get_name(monoClass));
|
|
||||||
_fullName = new $"{classNamespace}.{className}";
|
|
||||||
|
|
||||||
GetMessage(exObject, monoClass);
|
|
||||||
|
|
||||||
GetStackTrace(exception);
|
|
||||||
|
|
||||||
GetInnerException(exObject, monoClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GetMessage(MonoObject* exceptionObject, MonoClass* monoClass)
|
|
||||||
{
|
|
||||||
var messageProperty = Mono.mono_class_get_property_from_name(monoClass, "Message");
|
|
||||||
|
|
||||||
MonoObject* message = Mono.mono_property_get_value(messageProperty, exceptionObject, null, null);
|
|
||||||
char8* exMessage = Mono.mono_string_to_utf8((.)message);
|
|
||||||
|
|
||||||
_message = new String(exMessage);
|
|
||||||
|
|
||||||
Mono.mono_free(exMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GetStackTrace(MonoException* exception)
|
|
||||||
{
|
|
||||||
char8* stacktracePtr = Mono.mono_exception_get_managed_backtrace(exception);
|
|
||||||
_stackTrace = new String(stacktracePtr);
|
|
||||||
|
|
||||||
int entryIndex = _stackTrace.IndexOf("at (wrapper native-to-managed)");
|
|
||||||
|
|
||||||
if (entryIndex != -1)
|
|
||||||
_cleanStackTrace = _stackTrace.Substring(0, entryIndex);
|
|
||||||
else
|
|
||||||
_cleanStackTrace = _stackTrace;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GetInnerException(MonoObject* exceptionObject, MonoClass* monoClass)
|
|
||||||
{
|
|
||||||
MonoProperty* innerExceptionProperty = Mono.mono_class_get_property_from_name(monoClass, "InnerException");
|
|
||||||
|
|
||||||
MonoObject* innerException = Mono.mono_property_get_value(innerExceptionProperty, exceptionObject, null, null);
|
|
||||||
|
|
||||||
if (innerException != null)
|
|
||||||
_innerException = new MonoExceptionHelper((MonoException*)innerException);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -13,44 +13,13 @@ public struct ScriptField
|
|||||||
internal MonoClassField* _monoField;
|
internal MonoClassField* _monoField;
|
||||||
public bool IsStatic;
|
public bool IsStatic;
|
||||||
public ScriptFieldType FieldType;
|
public ScriptFieldType FieldType;
|
||||||
public SharpType SharpType;
|
|
||||||
public int SizeInBytes;
|
|
||||||
|
|
||||||
internal this(StringView name, MonoClassField* monoField, bool isStatic, ScriptFieldType fieldType, int sizeInBytes, SharpType sharpType)
|
internal this(StringView name, MonoClassField* monoField, bool isStatic, ScriptFieldType fieldType)
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
_monoField = monoField;
|
_monoField = monoField;
|
||||||
IsStatic = isStatic;
|
IsStatic = isStatic;
|
||||||
FieldType = fieldType;
|
FieldType = fieldType;
|
||||||
SharpType = sharpType;
|
|
||||||
SizeInBytes = sizeInBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsType(SharpClass otherClass, bool checkIfSubtype)
|
|
||||||
{
|
|
||||||
return IsType(otherClass.GetMonoType(), checkIfSubtype);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsType(MonoType* otherType, bool checkIfSubtype)
|
|
||||||
{
|
|
||||||
MonoType* myType = GetMonoType();
|
|
||||||
|
|
||||||
if (checkIfSubtype)
|
|
||||||
{
|
|
||||||
MonoClass* myClass = Mono.mono_type_get_class(myType);
|
|
||||||
MonoClass* otherClass = Mono.mono_type_get_class(otherType);
|
|
||||||
|
|
||||||
return Mono.mono_class_is_subclass_of(myClass, otherClass, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return myType == otherType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public MonoType* GetMonoType()
|
|
||||||
{
|
|
||||||
return Mono.mono_field_get_type(_monoField);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,19 +90,9 @@ class SharpClass : SharpType
|
|||||||
ExtractFields();
|
ExtractFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal MonoType* GetMonoType()
|
|
||||||
{
|
|
||||||
return Mono.mono_class_get_type(_monoClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal bool IsType(MonoType* type)
|
internal bool IsType(MonoType* type)
|
||||||
{
|
{
|
||||||
return GetMonoType() == type;
|
return Mono.mono_class_get_type(_monoClass) == type;
|
||||||
}
|
|
||||||
|
|
||||||
internal bool IsSubclass(MonoClass* @class)
|
|
||||||
{
|
|
||||||
return Mono.mono_class_is_subclass_of(_monoClass, @class, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ExtractFields()
|
private void ExtractFields()
|
||||||
@@ -151,12 +110,10 @@ class SharpClass : SharpType
|
|||||||
|
|
||||||
ScriptFieldType fieldType = ScriptEngineHelper.GetScriptFieldType(type);
|
ScriptFieldType fieldType = ScriptEngineHelper.GetScriptFieldType(type);
|
||||||
|
|
||||||
SharpType sharpType = null;
|
|
||||||
|
|
||||||
// If field type is none the field might be a struct, class or enum
|
// If field type is none the field might be a struct, class or enum
|
||||||
if (fieldType == .None)
|
if (fieldType == .None)
|
||||||
{
|
{
|
||||||
sharpType = ScriptEngine.GetSharpType(type);
|
SharpType sharpType = ScriptEngine.GetSharpType(type);
|
||||||
fieldType = sharpType?.ScriptType ?? .None;
|
fieldType = sharpType?.ScriptType ?? .None;
|
||||||
|
|
||||||
if (sharpType == null)
|
if (sharpType == null)
|
||||||
@@ -175,79 +132,7 @@ class SharpClass : SharpType
|
|||||||
(attributes != null &&
|
(attributes != null &&
|
||||||
Mono.mono_custom_attrs_has_attr(attributes, ScriptEngine.Attributes.s_ShowInEditorAttribute)))
|
Mono.mono_custom_attrs_has_attr(attributes, ScriptEngine.Attributes.s_ShowInEditorAttribute)))
|
||||||
{
|
{
|
||||||
MonoClass* fieldClass = Mono.mono_type_get_class(type);
|
_monoFields[name] = .(name, currentField, flags.HasFlag(.Static), fieldType);
|
||||||
|
|
||||||
int sizeInBytes = 8;
|
|
||||||
|
|
||||||
if (fieldClass != null)
|
|
||||||
{
|
|
||||||
sizeInBytes = Mono.mono_class_instance_size(fieldClass);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
_monoFields[name] = .(name, currentField, flags.HasFlag(.Static), fieldType, sizeInBytes, sharpType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct EnumValue
|
|
||||||
{
|
|
||||||
public StringView Name;
|
|
||||||
|
|
||||||
public uint64 Value;
|
|
||||||
|
|
||||||
public this(StringView name, uint64 value)
|
|
||||||
{
|
|
||||||
Name = name;
|
|
||||||
Value = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SharpEnum : SharpClass
|
|
||||||
{
|
|
||||||
private append Dictionary<uint64, EnumValue> _values = .();
|
|
||||||
|
|
||||||
public Dictionary<uint64, EnumValue> Values => _values;
|
|
||||||
|
|
||||||
private int _underlyingSize = 0;
|
|
||||||
|
|
||||||
public this(StringView classNamespace, StringView className, MonoImage* image)
|
|
||||||
: base(classNamespace, className, image, .Enum)
|
|
||||||
{
|
|
||||||
ExtractEnumValues();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ExtractEnumValues()
|
|
||||||
{
|
|
||||||
_underlyingSize = Mono.mono_class_instance_size(_monoClass);
|
|
||||||
Log.EngineLogger.Assert(_underlyingSize != 0);
|
|
||||||
|
|
||||||
var vtable = Mono.mono_class_vtable(ScriptEngine.[Friend]s_AppDomain, _monoClass);
|
|
||||||
|
|
||||||
void* iterator = null;
|
|
||||||
MonoClassField* currentField = null;
|
|
||||||
while ((currentField = Mono.mono_class_get_fields(_monoClass, &iterator)) != null)
|
|
||||||
{
|
|
||||||
MonoType* fieldType = Mono.mono_field_get_type(currentField);
|
|
||||||
MonoClass* fieldClass = Mono.mono_type_get_class(fieldType);
|
|
||||||
|
|
||||||
FieldAttribute fieldFlags = (.)Mono.mono_field_get_flags(currentField);
|
|
||||||
|
|
||||||
if (fieldFlags.HasFlag(.Public) && fieldFlags.HasFlag(.Static) &&
|
|
||||||
fieldClass != null && Mono.mono_class_is_subclass_of(fieldClass, _monoClass, false))
|
|
||||||
{
|
|
||||||
StringView fieldName = StringView(Mono.mono_field_get_name(currentField));
|
|
||||||
|
|
||||||
uint64 value = 0;
|
|
||||||
Mono.mono_field_static_get_value(vtable, currentField, &value);
|
|
||||||
|
|
||||||
EnumValue enumValue = .(fieldName, value);
|
|
||||||
|
|
||||||
_values.Add(value, enumValue);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -295,8 +180,8 @@ class ScriptClass : SharpClass
|
|||||||
public Dictionary<StringView, ScriptField> Fields => _monoFields;*/
|
public Dictionary<StringView, ScriptField> Fields => _monoFields;*/
|
||||||
|
|
||||||
[AllowAppend]
|
[AllowAppend]
|
||||||
public this(StringView classNamespace, StringView className, MonoImage* image, ScriptFieldType scriptFieldType = .Class) :
|
public this(StringView classNamespace, StringView className, MonoImage* image) :
|
||||||
base(classNamespace, className, image, scriptFieldType)
|
base(classNamespace, className, image)
|
||||||
{
|
{
|
||||||
//_constructor = (ConstructorMethod)GetMethodThunk(".ctor", 1); // GetMethod(".ctor", 1);//
|
//_constructor = (ConstructorMethod)GetMethodThunk(".ctor", 1); // GetMethod(".ctor", 1);//
|
||||||
_constructor = GetMethod(".ctor", 1);
|
_constructor = GetMethod(".ctor", 1);
|
||||||
@@ -305,50 +190,59 @@ class ScriptClass : SharpClass
|
|||||||
_onDestroy = (OnDestroyMethod)GetMethodThunk("OnDestroy");
|
_onDestroy = (OnDestroyMethod)GetMethodThunk("OnDestroy");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnCreate(MonoObject* instance, out MonoException* exception)
|
public void OnCreate(MonoObject* instance)
|
||||||
{
|
{
|
||||||
exception = null;
|
MonoException* exception = null;
|
||||||
|
|
||||||
if (_onCreate != null)
|
if (_onCreate != null)
|
||||||
_onCreate(instance, &exception);
|
_onCreate(instance, &exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnUpdate(MonoObject* instance, float deltaTime, out MonoException* exception)
|
public void OnUpdate(MonoObject* instance, float deltaTime)
|
||||||
{
|
{
|
||||||
exception = null;
|
MonoException* exception = null;
|
||||||
|
|
||||||
if (_onUpdate != null)
|
if (_onUpdate != null)
|
||||||
_onUpdate(instance, deltaTime, &exception);
|
_onUpdate(instance, deltaTime, &exception);
|
||||||
|
|
||||||
|
if (exception != null)
|
||||||
|
{
|
||||||
|
char8* str = Mono.mono_string_to_utf8(exception.Message);
|
||||||
|
|
||||||
|
Log.EngineLogger.Error($"Exception in \"{_fullName}.OnUpdate\". Message:\"{StringView(str)}\"");
|
||||||
|
|
||||||
|
Mono.mono_free(str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnDestroy(MonoObject* instance, out MonoException* exception)
|
public void OnDestroy(MonoObject* instance)
|
||||||
{
|
{
|
||||||
exception = null;
|
MonoException* exception;
|
||||||
|
|
||||||
if (_onDestroy != null)
|
if (_onDestroy != null)
|
||||||
_onDestroy(instance, &exception);
|
_onDestroy(instance, &exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MonoObject* CreateInstance(UUID uuid, out MonoException* exception)
|
public MonoObject* CreateInstance(UUID uuid)
|
||||||
{
|
{
|
||||||
MonoObject* instance = Mono.mono_object_new(ScriptEngine.[Friend]s_AppDomain, _monoClass);
|
MonoObject* instance = Mono.mono_object_new(ScriptEngine.[Friend]s_AppDomain, _monoClass);
|
||||||
|
|
||||||
|
// TODO: I think this is a bit dirty
|
||||||
// Invoke empty constructor to fill fields
|
// Invoke empty constructor to fill fields
|
||||||
Mono.mono_runtime_object_init(instance);
|
Mono.mono_runtime_object_init(instance);
|
||||||
|
|
||||||
// Invoke constructor with UUID
|
// Invoke constructor with UUID
|
||||||
#unwarn
|
#unwarn
|
||||||
ScriptEngine.[Friend]s_EngineObject.Invoke(ScriptEngine.[Friend]s_EngineObject._constructor, instance, out exception, &uuid);
|
ScriptEngine.[Friend]s_EngineObject.Invoke(ScriptEngine.[Friend]s_EngineObject._constructor, instance, &uuid);
|
||||||
|
|
||||||
return instance;
|
//MonoException* exception = null;
|
||||||
}
|
//#unwarn
|
||||||
|
//ScriptEngine.[Friend]s_EntityRoot._constructor(instance, uuid, &exception);
|
||||||
|
//ScriptEngine.[Friend]s_EntityRoot.Invoke(_constructor, instance, &uuid);
|
||||||
|
|
||||||
public MonoObject* CreateInstance()
|
/*MonoObject* exception = null;
|
||||||
{
|
#unwarn*/
|
||||||
MonoObject* instance = Mono.mono_object_new(ScriptEngine.[Friend]s_AppDomain, _monoClass);
|
//Mono.mono_runtime_invoke(_constructor, instance, (.)&uuid, &exception);
|
||||||
|
//Mono.mono_runtime_object_init(instance);
|
||||||
// Invoke empty constructor to fill fields
|
//MonoException* exception;
|
||||||
Mono.mono_runtime_object_init(instance);
|
//_constructor(instance, uuid, &exception);
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
@@ -371,22 +265,12 @@ class ScriptClass : SharpClass
|
|||||||
public MonoObject* Invoke(MonoMethod* method, MonoObject* instance, void** args = null)
|
public MonoObject* Invoke(MonoMethod* method, MonoObject* instance, void** args = null)
|
||||||
{
|
{
|
||||||
MonoObject* exception = null;
|
MonoObject* exception = null;
|
||||||
|
return Mono.mono_runtime_invoke(method, instance, args, &exception);
|
||||||
MonoObject* result = Mono.mono_runtime_invoke(method, instance, args, &exception);
|
|
||||||
|
|
||||||
if (exception != null)
|
|
||||||
ScriptEngine.HandleMonoException((MonoException*)exception);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MonoObject* Invoke(MonoMethod* method, MonoObject* instance, out MonoException* exception, params void*[] args)
|
public MonoObject* Invoke(MonoMethod* method, MonoObject* instance, params void*[] args)
|
||||||
{
|
{
|
||||||
exception = null;
|
return Mono.mono_runtime_invoke(method, instance, args.Ptr, null);
|
||||||
|
|
||||||
MonoObject* result = Mono.mono_runtime_invoke(method, instance, args.Ptr, (.)&exception);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public T Invoke<T>(MonoMethod* method, MonoObject* instance, params void*[] args)
|
public T Invoke<T>(MonoMethod* method, MonoObject* instance, params void*[] args)
|
||||||
@@ -398,17 +282,12 @@ class ScriptClass : SharpClass
|
|||||||
public T GetFieldValue<T>(MonoObject* instance, MonoClassField* field)
|
public T GetFieldValue<T>(MonoObject* instance, MonoClassField* field)
|
||||||
{
|
{
|
||||||
T value = default;
|
T value = default;
|
||||||
Mono.mono_field_get_value(instance, field, &value);
|
Mono.Mono.mono_field_get_value(instance, field, &value);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetFieldValue<T>(MonoObject* instance, MonoClassField* field, in T value)
|
public void SetFieldValue<T>(MonoObject* instance, MonoClassField* field, in T value)
|
||||||
{
|
{
|
||||||
Mono.mono_field_set_value(instance, field, &value);
|
Mono.Mono.mono_field_set_value(instance, field, &value);
|
||||||
}
|
|
||||||
|
|
||||||
public void SetFieldValue<T>(MonoObject* instance, MonoClassField* field, in T value) where T : struct*
|
|
||||||
{
|
|
||||||
Mono.mono_field_set_value(instance, field, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ using System.Collections;
|
|||||||
using GlitchyEngine.Core;
|
using GlitchyEngine.Core;
|
||||||
using GlitchyEngine.Math;
|
using GlitchyEngine.Math;
|
||||||
using GlitchyEngine.World;
|
using GlitchyEngine.World;
|
||||||
|
using NetHostBeef;
|
||||||
|
using System.Interop;
|
||||||
|
|
||||||
namespace GlitchyEngine.Scripting;
|
namespace GlitchyEngine.Scripting;
|
||||||
|
|
||||||
@@ -45,6 +47,73 @@ static sealed class ScriptEngineHelper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum ScriptMethods : uint32
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
OnCreate = 0x1,
|
||||||
|
OnUpdate = 0x2,
|
||||||
|
OnDestroy = 0x4,
|
||||||
|
}
|
||||||
|
|
||||||
|
class SexyScriptClass
|
||||||
|
{
|
||||||
|
public String FullName ~ delete _;
|
||||||
|
public StringView Name;
|
||||||
|
public Guid Guid;
|
||||||
|
public ScriptMethods Methods;
|
||||||
|
|
||||||
|
public this(StringView fullName, Guid guid, ScriptMethods methods)
|
||||||
|
{
|
||||||
|
FullName = new String(fullName);
|
||||||
|
Guid = guid;
|
||||||
|
|
||||||
|
int lastDotIndex = FullName.LastIndexOf('.');
|
||||||
|
|
||||||
|
if (lastDotIndex == -1)
|
||||||
|
Name = FullName;
|
||||||
|
else
|
||||||
|
Name = FullName.Substring(lastDotIndex + 1);
|
||||||
|
|
||||||
|
Methods = methods;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SexyScriptInstance
|
||||||
|
{
|
||||||
|
public SexyScriptClass ScriptClass;
|
||||||
|
|
||||||
|
public ScriptFunctionPointers Functions;
|
||||||
|
|
||||||
|
public this(SexyScriptClass scriptClass, ScriptFunctionPointers functions)
|
||||||
|
{
|
||||||
|
ScriptClass = scriptClass;
|
||||||
|
Functions = functions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InvokeOnCreate()
|
||||||
|
{
|
||||||
|
Functions.OnCreateMethod();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*public void InvokeOnUpdate(float deltaTime)
|
||||||
|
{
|
||||||
|
CoreClrHelper.InvokeOnUpdate(float deltaTime);
|
||||||
|
//Functions.OnUpdateMethod(deltaTime);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
public void InvokeOnDestroy()
|
||||||
|
{
|
||||||
|
Functions.OnDestroyMethod();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct ScriptFunctionPointers
|
||||||
|
{
|
||||||
|
public function void() OnCreateMethod;
|
||||||
|
public function void(float) OnUpdateMethod;
|
||||||
|
public function void() OnDestroyMethod;
|
||||||
|
}
|
||||||
|
|
||||||
static class ScriptEngine
|
static class ScriptEngine
|
||||||
{
|
{
|
||||||
private static MonoDomain* s_RootDomain;
|
private static MonoDomain* s_RootDomain;
|
||||||
@@ -58,25 +127,16 @@ static class ScriptEngine
|
|||||||
|
|
||||||
private static Scene s_Context ~ _?.ReleaseRef();
|
private static Scene s_Context ~ _?.ReleaseRef();
|
||||||
|
|
||||||
private static ScriptClass s_ComponentRoot ~ _?.ReleaseRef();
|
|
||||||
private static ScriptClass s_EntityRoot ~ _?.ReleaseRef();
|
private static ScriptClass s_EntityRoot ~ _?.ReleaseRef();
|
||||||
private static ScriptClass s_EngineObject ~ _?.ReleaseRef();
|
private static ScriptClass s_EngineObject ~ _?.ReleaseRef();
|
||||||
|
|
||||||
private static Dictionary<StringView, SharpType> _sharpClasses = new .() ~ DeleteDictionaryAndReleaseValues!(_);
|
private static Dictionary<StringView, SharpType> _sharpClasses = new .() ~ DeleteDictionaryAndReleaseValues!(_);
|
||||||
|
|
||||||
private static Dictionary<StringView, ScriptClass> _entityScripts = new .() ~ DeleteDictionaryAndReleaseValues!(_);
|
private static Dictionary<StringView, SexyScriptClass> _entityScripts = new .() ~ DeleteDictionaryAndValues!(_);
|
||||||
private static Dictionary<StringView, ScriptClass> _componentClasses = new .() ~ DeleteDictionaryAndReleaseValues!(_);
|
|
||||||
|
|
||||||
private static Dictionary<UUID, ScriptInstance> _entityScriptInstances = new .() ~ {
|
private static Dictionary<UUID, SexyScriptInstance> _entityScriptInstances = new .() ~ DeleteDictionaryAndValues!(_);
|
||||||
for (var entry in _)
|
|
||||||
{
|
|
||||||
entry.value?.ReleaseRef();
|
|
||||||
}
|
|
||||||
delete _;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<StringView, ScriptClass> EntityClasses => _entityScripts;
|
public static Dictionary<StringView, SexyScriptClass> EntityClasses => _entityScripts;
|
||||||
public static Dictionary<StringView, ScriptClass> ComponentClasses => _componentClasses;
|
|
||||||
|
|
||||||
public static Scene Context => s_Context;
|
public static Scene Context => s_Context;
|
||||||
|
|
||||||
@@ -99,49 +159,35 @@ static class ScriptEngine
|
|||||||
{
|
{
|
||||||
internal static MonoClass* s_ShowInEditorAttribute;
|
internal static MonoClass* s_ShowInEditorAttribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String _coreAssemblyPath = "resources/scripts/ScriptCore.dll";
|
||||||
|
private static String _appAssemblyPath = "SandboxProject/Assets/Scripts/bin/Sandbox.dll";
|
||||||
|
|
||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
{
|
||||||
InitMono();
|
CoreClrHelper.Init(_coreAssemblyPath);
|
||||||
ScriptGlue.Init();
|
|
||||||
|
|
||||||
LoadScriptAssemblies();
|
GetFunctions();
|
||||||
|
|
||||||
|
//ScriptGlue.Init();
|
||||||
|
|
||||||
|
LoadScriptAssembly();
|
||||||
|
|
||||||
InitAssemblyWatcher();
|
InitAssemblyWatcher();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void InitMono()
|
|
||||||
{
|
|
||||||
Mono.mono_set_assemblies_path("mono/lib");
|
|
||||||
|
|
||||||
if (_debuggingEnabled)
|
|
||||||
{
|
|
||||||
char8*[2] options = .(
|
|
||||||
"--debugger-agent=transport=dt_socket,address=127.0.0.1:2550,server=y,suspend=n,loglevel=3,logfile=MonoDebugger.log",
|
|
||||||
"--soft-breakpoints"
|
|
||||||
);
|
|
||||||
|
|
||||||
Mono.mono_jit_parse_options(options.Count, &options);
|
|
||||||
Mono.mono_debug_init(.Mono);
|
|
||||||
}
|
|
||||||
|
|
||||||
s_RootDomain = Mono.mono_jit_init("GlitchyEngineJITRuntime");
|
|
||||||
Log.EngineLogger.Assert(s_RootDomain != null, "Failed to initialize mono root domain");
|
|
||||||
|
|
||||||
if (_debuggingEnabled)
|
|
||||||
{
|
|
||||||
Mono.mono_debug_domain_create(s_RootDomain);
|
|
||||||
}
|
|
||||||
|
|
||||||
Mono.mono_thread_set_main(Mono.mono_thread_current());
|
|
||||||
}
|
|
||||||
|
|
||||||
static void InitAssemblyWatcher()
|
static void InitAssemblyWatcher()
|
||||||
{
|
{
|
||||||
if (_userAssemblyWatcher == null)
|
if (_userAssemblyWatcher == null)
|
||||||
{
|
{
|
||||||
|
String directoryPath = scope String();
|
||||||
|
Path.GetDirectoryPath(_appAssemblyPath, directoryPath);
|
||||||
|
String fileName = scope String();
|
||||||
|
Path.GetFileName(_appAssemblyPath, fileName);
|
||||||
|
|
||||||
// TODO: Obviously don't hardcode path
|
// TODO: Obviously don't hardcode path
|
||||||
_userAssemblyWatcher = new FileSystemWatcher("SandboxProject/Assets/Scripts/bin/", "*/Sandbox.dll");
|
_userAssemblyWatcher = new FileSystemWatcher(directoryPath, fileName);
|
||||||
_userAssemblyWatcher.OnChanged.Add(new (fileName) =>
|
_userAssemblyWatcher.OnChanged.Add(new (fileName) =>
|
||||||
{
|
{
|
||||||
// TODO: Temporary, we want to be able to reload while in play-mode. (+ Editor Scripts will be a thing some day)
|
// TODO: Temporary, we want to be able to reload while in play-mode. (+ Editor Scripts will be a thing some day)
|
||||||
@@ -168,24 +214,44 @@ static class ScriptEngine
|
|||||||
_userAssemblyWatcher.StartRaisingEvents();
|
_userAssemblyWatcher.StartRaisingEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LoadScriptAssemblies()
|
static void LoadScriptAssembly()
|
||||||
{
|
{
|
||||||
CreateAppDomain("GlitchyEngineScriptRuntime");
|
List<uint8> data = new List<uint8>(1024);
|
||||||
(s_CoreAssembly, s_CoreAssemblyImage) = LoadAssembly("resources/scripts/ScriptCore.dll", _debuggingEnabled);
|
File.ReadAll(_appAssemblyPath, data);
|
||||||
(s_AppAssembly, s_AppAssemblyImage) = LoadAssembly("SandboxProject/Assets/Scripts/bin/Sandbox.dll", _debuggingEnabled);
|
|
||||||
|
|
||||||
ClearDictionaryAndReleaseValues!(_sharpClasses);
|
List<uint8> pdbData = new List<uint8>(1024);
|
||||||
|
|
||||||
GetCoreAttributes();
|
String pdbPath = scope .();
|
||||||
GetCoreClasses();
|
Path.ChangeExtension(_appAssemblyPath, ".pdb", pdbPath);
|
||||||
|
|
||||||
GetComponentsFromAssemblies();
|
File.ReadAll(pdbPath, pdbData);
|
||||||
|
|
||||||
|
CoreClrHelper.LoadAppAssembly(data, pdbData);
|
||||||
|
|
||||||
|
delete data;
|
||||||
|
delete pdbData;
|
||||||
|
|
||||||
GetEntitiesFromAssemblies();
|
GetEntitiesFromAssemblies();
|
||||||
|
|
||||||
ScriptGlue.RegisterManagedComponents();
|
//ScriptGlue.RegisterManagedComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ReloadAssemblies()
|
||||||
|
{
|
||||||
|
Debug.Profiler.ProfileFunction!();
|
||||||
|
|
||||||
|
CoreClrHelper.UnloadAssemblies();
|
||||||
|
LoadScriptAssembly();
|
||||||
|
|
||||||
|
// TODO: ScriptFields might get added
|
||||||
|
// TODO: ScriptField Types may change after reload!
|
||||||
|
// TODO: Scripts may be renamed (probably not detectable (trivially))
|
||||||
|
|
||||||
|
// TODO: Reload in play mode
|
||||||
|
// Only scripts that were changed should actually be reinstatiated
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void SetContext(Scene scene)
|
public static void SetContext(Scene scene)
|
||||||
{
|
{
|
||||||
SetReference!(s_Context, scene);
|
SetReference!(s_Context, scene);
|
||||||
@@ -193,167 +259,152 @@ static class ScriptEngine
|
|||||||
|
|
||||||
public static void OnRuntimeStop()
|
public static void OnRuntimeStop()
|
||||||
{
|
{
|
||||||
for (var entry in _entityScriptInstances)
|
ThrowUnimplemented();
|
||||||
|
|
||||||
|
// TODO: Also check, if something has to happen on the C# side!
|
||||||
|
|
||||||
|
ClearDictionaryAndDeleteValues!(_entityScriptInstances);
|
||||||
|
|
||||||
|
/*for (var entry in _entityScriptInstances)
|
||||||
{
|
{
|
||||||
entry.value.ReleaseRef();
|
entry.value.ReleaseRef();
|
||||||
}
|
}
|
||||||
_entityScriptInstances.Clear();
|
_entityScriptInstances.Clear();
|
||||||
|
*/
|
||||||
SetContext(null);
|
SetContext(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function void InvokeOnUpdateFunc(UUID entityId, float deltaTime);
|
||||||
|
|
||||||
|
private static InvokeOnUpdateFunc _InvokeOnUpdate;
|
||||||
|
|
||||||
|
private static void GetFunctions()
|
||||||
|
{
|
||||||
|
CoreClrHelper.GetFunctionPointerUnmanagedCallersOnly("GlitchyEngine.ScriptGlue, ScriptCore", "InvokeOnUpdate", out _InvokeOnUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
public static bool InitializeInstance(Entity entity, ScriptComponent* script)
|
public static bool InitializeInstance(Entity entity, ScriptComponent* script)
|
||||||
{
|
{
|
||||||
ScriptClass scriptClass = GetScriptClass(script.ScriptClassName);
|
SexyScriptClass scriptClass = GetScriptClass(script.ScriptClassName);
|
||||||
|
|
||||||
if (scriptClass == null)
|
if (scriptClass == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
ScriptFunctionPointers functions = CoreClrHelper.CreateScriptInstance(entity.UUID, scriptClass.FullName);
|
||||||
|
|
||||||
UUID entityId = entity.UUID;
|
script.Instance = new SexyScriptInstance(scriptClass, functions);//new ScriptInstance(scriptClass);
|
||||||
|
// script.Instance..ReleaseRef();
|
||||||
|
|
||||||
|
_entityScriptInstances[entity.UUID] = script.Instance;
|
||||||
|
|
||||||
script.Instance = new ScriptInstance(entityId, scriptClass);
|
// CopyEditorFieldsToInstance(entity, script);
|
||||||
script.Instance..ReleaseRef();
|
|
||||||
|
|
||||||
_entityScriptInstances[entityId] = script.Instance..AddRef();
|
|
||||||
|
|
||||||
script.Instance.Instantiate(entityId);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void CopyEditorFieldsToInstance(Entity entity, ScriptComponent* script)
|
private static void CopyEditorFieldsToInstance(Entity entity, ScriptComponent* script)
|
||||||
{
|
{
|
||||||
Log.EngineLogger.AssertDebug(script.Instance != null);
|
ThrowUnimplemented();
|
||||||
|
|
||||||
// Technically the map is for a different entity (namely the editor-entity),
|
/*// Technically the map is for a different entity (namely the editor-entity),
|
||||||
// however the UUID is the same, so we get the correct field map
|
// however the UUID is the same, so we get the correct field map
|
||||||
let fields = GetScriptFieldMap(entity);
|
let fields = GetScriptFieldMap(entity);
|
||||||
|
|
||||||
for (var (fieldName, field) in fields)
|
for (var (fieldName, field) in fields)
|
||||||
{
|
{
|
||||||
// TODO: a litte assertion maybe?
|
// TODO: a litte assertion maybe?
|
||||||
|
|
||||||
ScriptField scriptField = script.Instance.ScriptClass.Fields[fieldName];
|
ScriptField scriptField = script.Instance.ScriptClass.Fields[fieldName];
|
||||||
|
|
||||||
switch (scriptField.FieldType)
|
script.Instance.SetFieldValue(scriptField, field._data);
|
||||||
{
|
}*/
|
||||||
case .Entity:
|
|
||||||
// On the C# side we actually differentiate between an Entity and the Script
|
|
||||||
// in the sense that getting an entity and a script yields two different results (one creates a new Entity-Class instance, the other returns the actual instance).
|
|
||||||
// But here its just easier to always use the script instance.
|
|
||||||
// Obviously breaks once we support multiple scripts per entity.
|
|
||||||
UUID referencedId = field.GetData<UUID>();
|
|
||||||
MonoObject* referencedEntity = GetManagedInstance(referencedId);
|
|
||||||
script.Instance.SetFieldValue(scriptField, referencedEntity);
|
|
||||||
case .Component:
|
|
||||||
// We create a new instance of a component class
|
|
||||||
MonoType* type = scriptField.GetMonoType();
|
|
||||||
|
|
||||||
SharpType sharpType = ScriptEngine.GetSharpType(type);
|
|
||||||
|
|
||||||
var componentClass = ComponentClasses[sharpType.FullName];
|
|
||||||
|
|
||||||
MonoObject* componentInstance = script.Instance.CreateComponentInstance(componentClass);
|
|
||||||
script.Instance.SetFieldValue(scriptField, componentInstance);
|
|
||||||
|
|
||||||
sharpType.ReleaseRef();
|
|
||||||
default:
|
|
||||||
script.Instance.SetFieldValue(scriptField, field._data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MonoAssembly* LoadCSharpAssembly(StringView assemblyPath, bool loadPDB = false)
|
struct ScriptClassInfo
|
||||||
{
|
{
|
||||||
List<uint8> data = new List<uint8>(1024);
|
public char8* Name;
|
||||||
|
public Guid Guid;
|
||||||
File.ReadAll(assemblyPath, data);
|
public ScriptMethods Methods;
|
||||||
|
|
||||||
// NOTE: We can't use this image for anything other than loading the assembly because this image doesn't have a reference to the assembly
|
|
||||||
MonoImageOpenStatus status = .ImageInvalid;
|
|
||||||
MonoImage* image = Mono.mono_image_open_from_data_full(data.Ptr, (.)data.Count, true, &status, false);
|
|
||||||
|
|
||||||
delete data;
|
|
||||||
|
|
||||||
if (status != .Ok)
|
|
||||||
{
|
|
||||||
char8* errorMessage = Mono.mono_image_strerror(status);
|
|
||||||
|
|
||||||
Log.EngineLogger.Error($"Failed to load C# Assembly: \"{StringView(errorMessage)}\"");
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loadPDB)
|
|
||||||
{
|
|
||||||
String pdbPath = scope .();
|
|
||||||
Path.ChangeExtension(assemblyPath, ".pdb", pdbPath);
|
|
||||||
|
|
||||||
if (File.Exists(pdbPath))
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Trace($"Loading PDB \"{pdbPath}\"...");
|
|
||||||
|
|
||||||
List<uint8> pdbData = new List<uint8>(1024);
|
|
||||||
|
|
||||||
let result = File.ReadAll(pdbPath, pdbData);
|
|
||||||
|
|
||||||
if (result case .Err(let error))
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Error("Failed to load PDB file ({error}).");
|
|
||||||
}
|
|
||||||
|
|
||||||
Mono.mono_debug_open_image_from_memory(image, pdbData.Ptr, (int32)pdbData.Count);
|
|
||||||
|
|
||||||
delete pdbData;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Warning($"Debugging enabled but no PDB-File found \"{assemblyPath}\".");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MonoAssembly* assembly = Mono.mono_assembly_load_from_full(image, assemblyPath.ToScopeCStr!(), &status, 0);
|
|
||||||
|
|
||||||
Mono.mono_image_close(image);
|
|
||||||
|
|
||||||
return assembly;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void CreateAppDomain(StringView name)
|
|
||||||
{
|
|
||||||
s_AppDomain = Mono.mono_domain_create_appdomain(name.ToScopeCStr!(), null);
|
|
||||||
Mono.mono_domain_set(s_AppDomain, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static (MonoAssembly* assembly, MonoImage* image) LoadAssembly(StringView filepath, bool loadPDB = false)
|
|
||||||
{
|
|
||||||
MonoAssembly* assembly = LoadCSharpAssembly(filepath, loadPDB);
|
|
||||||
MonoImage* image = Mono.mono_assembly_get_image(assembly);
|
|
||||||
|
|
||||||
return (assembly, image);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves the base classes from which every Component or Entity inherits
|
|
||||||
static void GetCoreClasses()
|
|
||||||
{
|
|
||||||
s_EngineObject?.ReleaseRef();
|
|
||||||
s_EntityRoot?.ReleaseRef();
|
|
||||||
s_ComponentRoot?.ReleaseRef();
|
|
||||||
|
|
||||||
s_EngineObject = new ScriptClass("GlitchyEngine.Core", "EngineObject", s_CoreAssemblyImage, .Class);
|
|
||||||
s_EntityRoot = new ScriptClass("GlitchyEngine", "Entity", s_CoreAssemblyImage, .Entity);
|
|
||||||
s_ComponentRoot = new ScriptClass("GlitchyEngine", "Component", s_CoreAssemblyImage, .Component);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves the classes for Attributes that are defined in the Core library
|
|
||||||
static void GetCoreAttributes()
|
|
||||||
{
|
|
||||||
Attributes.s_ShowInEditorAttribute = Mono.mono_class_from_name(s_CoreAssemblyImage, "GlitchyEngine.Editor", "ShowInEditorAttribute");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void GetEntitiesFromAssemblies()
|
private static void GetEntitiesFromAssemblies()
|
||||||
{
|
{
|
||||||
ClearDictionaryAndReleaseValues!(_entityScripts);
|
CoreClrHelper.GetScriptClasses(let data, let entryCount);
|
||||||
|
|
||||||
|
Span<ScriptClassInfo> scriptClasses = .((.)data, entryCount);
|
||||||
|
|
||||||
|
List<SexyScriptClass> newClasses = scope .();
|
||||||
|
|
||||||
|
for (var entry in _entityScripts)
|
||||||
|
{
|
||||||
|
bool remove = true;
|
||||||
|
|
||||||
|
// We can only rely on guids.
|
||||||
|
for (var newEntry in scriptClasses)
|
||||||
|
{
|
||||||
|
if (entry.value.Guid == newEntry.Guid)
|
||||||
|
{
|
||||||
|
remove = false;
|
||||||
|
|
||||||
|
if (!String.Equals(entry.value.FullName.CStr(), newEntry.Name))
|
||||||
|
{
|
||||||
|
@entry.Remove();
|
||||||
|
|
||||||
|
entry.value.FullName.Set(StringView(newEntry.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
newClasses.Add(entry.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remove)
|
||||||
|
{
|
||||||
|
@entry.Remove();
|
||||||
|
|
||||||
|
delete entry.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entry in scriptClasses)
|
||||||
|
{
|
||||||
|
SexyScriptClass scriptClass = new .(StringView(entry.Name), entry.Guid, entry.Methods);
|
||||||
|
|
||||||
|
newClasses.Add(scriptClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var scriptClass in newClasses)
|
||||||
|
{
|
||||||
|
_entityScripts.Add(scriptClass.FullName, scriptClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
CoreClrHelper.FreeScriptClassNames();
|
||||||
|
|
||||||
|
// TODO: Cleanup
|
||||||
|
|
||||||
|
/*for (var entry in _entityScripts)
|
||||||
|
{
|
||||||
|
entry.value.ReleaseRef();
|
||||||
|
}
|
||||||
|
_entityScripts.Clear();
|
||||||
|
|
||||||
|
for (var sharpClass in _sharpClasses)
|
||||||
|
{
|
||||||
|
sharpClass.value.ReleaseRef();
|
||||||
|
}
|
||||||
|
_sharpClasses.Clear();
|
||||||
|
|
||||||
|
if (s_EngineObject != null)
|
||||||
|
{
|
||||||
|
s_EngineObject.ReleaseRef();
|
||||||
|
s_EntityRoot.ReleaseRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
s_EngineObject = new ScriptClass("GlitchyEngine.Core", "EngineObject", s_CoreAssemblyImage);
|
||||||
|
s_EntityRoot = new ScriptClass("GlitchyEngine", "Entity", s_CoreAssemblyImage);
|
||||||
|
|
||||||
|
Log.EngineLogger.Assert(s_EntityRoot != null);
|
||||||
|
|
||||||
|
Attributes.s_ShowInEditorAttribute = Mono.mono_class_from_name(s_CoreAssemblyImage, "GlitchyEngine.Editor", "ShowInEditorAttribute");
|
||||||
|
|
||||||
MonoTableInfo* typeDefinitionsTable = Mono.mono_image_get_table_info(s_AppAssemblyImage, .MONO_TABLE_TYPEDEF);
|
MonoTableInfo* typeDefinitionsTable = Mono.mono_image_get_table_info(s_AppAssemblyImage, .MONO_TABLE_TYPEDEF);
|
||||||
int32 numTypes = Mono.mono_table_info_get_rows(typeDefinitionsTable);
|
int32 numTypes = Mono.mono_table_info_get_rows(typeDefinitionsTable);
|
||||||
@@ -367,72 +418,26 @@ static class ScriptEngine
|
|||||||
char8* name = Mono.mono_metadata_string_heap(s_AppAssemblyImage, (.)cols[(.)SOME_RANDOM_ENUM.MONO_TYPEDEF_NAME]);
|
char8* name = Mono.mono_metadata_string_heap(s_AppAssemblyImage, (.)cols[(.)SOME_RANDOM_ENUM.MONO_TYPEDEF_NAME]);
|
||||||
|
|
||||||
MonoClass* monoClass = Mono.mono_class_from_name(s_AppAssemblyImage, nameSpace, name);
|
MonoClass* monoClass = Mono.mono_class_from_name(s_AppAssemblyImage, nameSpace, name);
|
||||||
|
|
||||||
// Check if it is an entity
|
|
||||||
if (monoClass != null && Mono.mono_class_is_subclass_of(monoClass, s_EntityRoot.[Friend]_monoClass, false))
|
if (monoClass != null && Mono.mono_class_is_subclass_of(monoClass, s_EntityRoot.[Friend]_monoClass, false))
|
||||||
{
|
{
|
||||||
ScriptClass entityScript = new ScriptClass(StringView(nameSpace), StringView(name), s_AppAssemblyImage, .Entity);
|
ScriptClass entityScript = new ScriptClass(StringView(nameSpace), StringView(name), s_AppAssemblyImage);
|
||||||
_entityScripts.Add(entityScript.FullName, entityScript);
|
_entityScripts.Add(entityScript.FullName, entityScript);
|
||||||
|
|
||||||
Log.EngineLogger.Info($"Added entity \"{entityScript.FullName}\"");
|
Log.EngineLogger.Info($"Added entity \"{entityScript.FullName}\"");
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
|
||||||
private static void GetComponentsFromAssemblies()
|
|
||||||
{
|
|
||||||
ClearDictionaryAndReleaseValues!(_componentClasses);
|
|
||||||
|
|
||||||
MonoTableInfo* typeDefinitionsTable = Mono.mono_image_get_table_info(s_CoreAssemblyImage, .MONO_TABLE_TYPEDEF);
|
|
||||||
int32 numTypes = Mono.mono_table_info_get_rows(typeDefinitionsTable);
|
|
||||||
|
|
||||||
for (int32 i = 0; i < numTypes; i++)
|
|
||||||
{
|
|
||||||
int32[(.)SOME_RANDOM_ENUM.MONO_TYPEDEF_SIZE] cols = .();
|
|
||||||
Mono.mono_metadata_decode_row(typeDefinitionsTable, i, (.)&cols, (.)SOME_RANDOM_ENUM.MONO_TYPEDEF_SIZE);
|
|
||||||
|
|
||||||
char8* nameSpace = Mono.mono_metadata_string_heap(s_CoreAssemblyImage, (.)cols[(.)SOME_RANDOM_ENUM.MONO_TYPEDEF_NAMESPACE]);
|
|
||||||
char8* name = Mono.mono_metadata_string_heap(s_CoreAssemblyImage, (.)cols[(.)SOME_RANDOM_ENUM.MONO_TYPEDEF_NAME]);
|
|
||||||
|
|
||||||
MonoClass* monoClass = Mono.mono_class_from_name(s_CoreAssemblyImage, nameSpace, name);
|
|
||||||
|
|
||||||
// Check if it is a component but not the root Component class
|
|
||||||
if (monoClass != null && monoClass != s_ComponentRoot.[Friend]_monoClass && Mono.mono_class_is_subclass_of(monoClass, s_ComponentRoot.[Friend]_monoClass, false))
|
|
||||||
{
|
|
||||||
ScriptClass componentClass = new ScriptClass(StringView(nameSpace), StringView(name), s_CoreAssemblyImage, .Component);
|
|
||||||
_componentClasses.Add(componentClass.FullName, componentClass);
|
|
||||||
|
|
||||||
Log.EngineLogger.Info($"Added component \"{componentClass.FullName}\"");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ReloadAssemblies()
|
|
||||||
{
|
|
||||||
Debug.Profiler.ProfileFunction!();
|
|
||||||
|
|
||||||
Mono.mono_domain_set(s_RootDomain, false);
|
|
||||||
|
|
||||||
Mono.mono_domain_unload(s_AppDomain);
|
|
||||||
|
|
||||||
LoadScriptAssemblies();
|
|
||||||
|
|
||||||
// TODO: ScriptFields might get added
|
|
||||||
// TODO: ScriptField Types may change after reload!
|
|
||||||
// TODO: Scripts may be renamed (probably not detectable (trivially))
|
|
||||||
|
|
||||||
// TODO: Reload in play mode
|
|
||||||
// Only scripts that were changed should actually be reinstatiated
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Shutdown()
|
public static void Shutdown()
|
||||||
{
|
{
|
||||||
Mono.mono_domain_set(s_RootDomain, false);
|
/*Mono.mono_domain_set(s_RootDomain, false);
|
||||||
|
|
||||||
Mono.mono_domain_unload(s_AppDomain);
|
Mono.mono_domain_unload(s_AppDomain);
|
||||||
s_AppDomain = null;
|
s_AppDomain = null;
|
||||||
|
|
||||||
Mono.mono_jit_cleanup(s_RootDomain);
|
Mono.mono_jit_cleanup(s_RootDomain);
|
||||||
s_RootDomain = null;
|
s_RootDomain = null;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void RegisterSharpType(SharpType sharpType)
|
internal static void RegisterSharpType(SharpType sharpType)
|
||||||
@@ -458,44 +463,34 @@ static class ScriptEngine
|
|||||||
StringView classNamespace = StringView(Mono.mono_class_get_namespace(monoClass));
|
StringView classNamespace = StringView(Mono.mono_class_get_namespace(monoClass));
|
||||||
|
|
||||||
// TODO: at the moment only allow user-structs
|
// TODO: at the moment only allow user-structs
|
||||||
//if (classNamespace.StartsWith("GlitchyEngine"))
|
if (classNamespace.StartsWith("GlitchyEngine"))
|
||||||
// return null;
|
return null;
|
||||||
|
|
||||||
ScriptFieldType scriptType = .None;
|
|
||||||
|
|
||||||
if (Mono.mono_class_is_enum(monoClass))
|
switch (fieldType)
|
||||||
{
|
{
|
||||||
scriptType = .Enum;
|
case .Class, .Valuetype, .Enum:
|
||||||
|
ScriptFieldType scriptType = .None;
|
||||||
|
|
||||||
return new SharpEnum(classNamespace, className, Mono.mono_class_get_image(monoClass));
|
if (fieldType == .Class)
|
||||||
}
|
|
||||||
else if (fieldType == .Class)
|
|
||||||
{
|
|
||||||
if (Mono.mono_class_is_subclass_of(monoClass, s_EntityRoot._monoClass, false))
|
|
||||||
{
|
|
||||||
scriptType = .Entity;
|
|
||||||
}
|
|
||||||
else if (Mono.mono_class_is_subclass_of(monoClass, s_ComponentRoot._monoClass, false))
|
|
||||||
{
|
|
||||||
scriptType = .Component;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
scriptType = .Class;
|
scriptType = .Class;
|
||||||
}
|
else if (fieldType == .Enum)
|
||||||
}
|
scriptType = .Enum;
|
||||||
else if (fieldType == .Valuetype)
|
else if (fieldType == .Valuetype)
|
||||||
{
|
scriptType = .Struct;
|
||||||
scriptType = .Struct;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(scriptType != .None);
|
Log.EngineLogger.AssertDebug(scriptType != .None);
|
||||||
|
|
||||||
return new SharpClass(classNamespace, className, Mono.mono_class_get_image(monoClass), scriptType);
|
return new SharpClass(classNamespace, className, Mono.mono_class_get_image(monoClass), scriptType);
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void CreateScriptFieldMap(Entity entity)
|
public static void CreateScriptFieldMap(Entity entity)
|
||||||
{
|
{
|
||||||
|
Log.EngineLogger.Error("Not implemented");
|
||||||
|
|
||||||
|
/*
|
||||||
Log.EngineLogger.AssertDebug(entity.IsValid);
|
Log.EngineLogger.AssertDebug(entity.IsValid);
|
||||||
|
|
||||||
if (_entityFields.TryGetValue(entity.UUID, var entityFields))
|
if (_entityFields.TryGetValue(entity.UUID, var entityFields))
|
||||||
@@ -514,28 +509,16 @@ static class ScriptEngine
|
|||||||
|
|
||||||
Log.EngineLogger.AssertDebug(scriptClass != null);
|
Log.EngineLogger.AssertDebug(scriptClass != null);
|
||||||
|
|
||||||
void AddFieldsToMap(Dictionary<StringView, ScriptField> classFields, StringView baseName)
|
for (let (fieldName, field) in scriptClass.Fields)
|
||||||
{
|
{
|
||||||
for (let (fieldName, field) in classFields)
|
entityFields.Add(new String(fieldName), ScriptFieldInstance(field.FieldType));
|
||||||
{
|
}*/
|
||||||
/*if (field.FieldType == .Struct && field.SharpType != null)
|
|
||||||
{
|
|
||||||
AddFieldsToMap(field.SharpType.Fields, scope $"{baseName}{fieldName}.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
entityFields.Add(new $"{baseName}{fieldName}", ScriptFieldInstance(field.FieldType));
|
|
||||||
}*/
|
|
||||||
|
|
||||||
entityFields.Add(new String(fieldName), ScriptFieldInstance(field.FieldType));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AddFieldsToMap(scriptClass.Fields, "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ScriptFieldMap GetScriptFieldMap(Entity entity)
|
public static ScriptFieldMap GetScriptFieldMap(Entity entity)
|
||||||
{
|
{
|
||||||
|
ThrowUnimplemented();
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(entity.IsValid);
|
Log.EngineLogger.AssertDebug(entity.IsValid);
|
||||||
|
|
||||||
let uuid = entity.UUID;
|
let uuid = entity.UUID;
|
||||||
@@ -548,39 +531,23 @@ static class ScriptEngine
|
|||||||
|
|
||||||
public static MonoObject* GetManagedInstance(UUID entityId)
|
public static MonoObject* GetManagedInstance(UUID entityId)
|
||||||
{
|
{
|
||||||
if (_entityScriptInstances.TryGetValue(entityId, let scriptInstance))
|
ThrowUnimplemented();
|
||||||
return scriptInstance.MonoInstance;
|
|
||||||
|
/*if (_entityScriptInstances.TryGetValue(entityId, let scriptInstance))
|
||||||
|
return scriptInstance.MonoInstance;*/
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ScriptClass GetScriptClass(StringView name)
|
public static SexyScriptClass GetScriptClass(StringView name)
|
||||||
{
|
{
|
||||||
EntityClasses.TryGetValue(name, let scriptClass);
|
EntityClasses.TryGetValue(name, let scriptClass);
|
||||||
|
|
||||||
return scriptClass;
|
return scriptClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void HandleMonoException(MonoException* exception, ScriptInstance sourceInstance = null)
|
public static void InvokeOnUpdate(UUID entityId, float deltaTime)
|
||||||
{
|
{
|
||||||
MonoExceptionHelper wrappedException = new MonoExceptionHelper(exception);
|
_InvokeOnUpdate(entityId, deltaTime);
|
||||||
|
|
||||||
String entityInfo = scope .();
|
|
||||||
|
|
||||||
if (sourceInstance != null)
|
|
||||||
{
|
|
||||||
wrappedException.Instance = sourceInstance.EntityId;
|
|
||||||
|
|
||||||
Result<Entity> sourceEntity = Context.GetEntityByID(sourceInstance.EntityId);
|
|
||||||
|
|
||||||
if (sourceEntity case .Ok(let e))
|
|
||||||
{
|
|
||||||
entityInfo.AppendF($" ({e.Name} | {sourceInstance.EntityId})");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.ClientLogger.Error($"Mono Exception \"{wrappedException.FullName}\": \"{wrappedException.Message}\"{entityInfo}\nStackTrace:\n{wrappedException.StackTrace}", wrappedException);
|
|
||||||
|
|
||||||
wrappedException.ReleaseRef();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,7 +27,6 @@ enum ScriptFieldType
|
|||||||
case Double, Double2, Double3, Double4;
|
case Double, Double2, Double3, Double4;
|
||||||
|
|
||||||
case Entity;
|
case Entity;
|
||||||
case Component;
|
|
||||||
|
|
||||||
public Type GetBeefType()
|
public Type GetBeefType()
|
||||||
{
|
{
|
||||||
@@ -80,8 +79,6 @@ enum ScriptFieldType
|
|||||||
|
|
||||||
case .Entity:
|
case .Entity:
|
||||||
return typeof(UUID);
|
return typeof(UUID);
|
||||||
case .Component:
|
|
||||||
return typeof(UUID);
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ static class ScriptGlue
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adding this attribute to a method will log method entry and returned Result<T> errors */
|
/*/* Adding this attribute to a method will log method entry and returned Result<T> errors */
|
||||||
[AttributeUsage(.Method)]
|
[AttributeUsage(.Method)]
|
||||||
struct RegisterMethodAttribute : Attribute, IOnMethodInit
|
struct RegisterMethodAttribute : Attribute, IOnMethodInit
|
||||||
{
|
{
|
||||||
@@ -48,13 +48,13 @@ static class ScriptGlue
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
{
|
||||||
RegisterCalls();
|
//RegisterCalls();
|
||||||
|
|
||||||
RegisterMathFunctions();
|
//RegisterMathFunctions();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RegisterManagedComponents()
|
public static void RegisterManagedComponents()
|
||||||
@@ -67,11 +67,11 @@ static class ScriptGlue
|
|||||||
RegisterComponent<Rigidbody2DComponent>("GlitchyEngine.RigidBody2D");
|
RegisterComponent<Rigidbody2DComponent>("GlitchyEngine.RigidBody2D");
|
||||||
}
|
}
|
||||||
|
|
||||||
[RegisterMethod]
|
/*[RegisterMethod]
|
||||||
private static void RegisterCalls()
|
private static void RegisterCalls()
|
||||||
{
|
{
|
||||||
// Generated at CompTime
|
// Generated at CompTime
|
||||||
}
|
}*/
|
||||||
|
|
||||||
private static void RegisterComponent<T>(StringView cSharpClassName = "") where T : struct, new
|
private static void RegisterComponent<T>(StringView cSharpClassName = "") where T : struct, new
|
||||||
{
|
{
|
||||||
@@ -104,13 +104,10 @@ static class ScriptGlue
|
|||||||
}
|
}
|
||||||
|
|
||||||
[RegisterCall("Log::LogMessage_Impl")]
|
[RegisterCall("Log::LogMessage_Impl")]
|
||||||
static void Log(int32 logLevel, MonoString* message)
|
[Export, LinkName("Log::LogMessage_Impl"), CallingConvention(.Cdecl)]
|
||||||
|
static void Log(int32 logLevel, char8* message)
|
||||||
{
|
{
|
||||||
char8* utfMessage = Mono.mono_string_to_utf8(message);
|
Log.ClientLogger.Log((LogLevel)logLevel, StringView(message));
|
||||||
|
|
||||||
Log.ClientLogger.Log((LogLevel)logLevel, StringView(utfMessage));
|
|
||||||
|
|
||||||
Mono.mono_free(utfMessage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Input
|
#region Input
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ using System;
|
|||||||
|
|
||||||
namespace GlitchyEngine.Scripting;
|
namespace GlitchyEngine.Scripting;
|
||||||
|
|
||||||
using internal GlitchyEngine.Scripting;
|
|
||||||
|
|
||||||
class ScriptInstance : RefCounter
|
class ScriptInstance : RefCounter
|
||||||
{
|
{
|
||||||
private ScriptClass _scriptClass;
|
private ScriptClass _scriptClass;
|
||||||
@@ -13,8 +11,6 @@ class ScriptInstance : RefCounter
|
|||||||
private MonoObject* _instance;
|
private MonoObject* _instance;
|
||||||
private uint32 _gcHandle;
|
private uint32 _gcHandle;
|
||||||
|
|
||||||
private UUID _entityId;
|
|
||||||
|
|
||||||
public ScriptClass ScriptClass => _scriptClass;
|
public ScriptClass ScriptClass => _scriptClass;
|
||||||
|
|
||||||
/// Gets whether or not the instance has ben initialized.
|
/// Gets whether or not the instance has ben initialized.
|
||||||
@@ -25,15 +21,9 @@ class ScriptInstance : RefCounter
|
|||||||
|
|
||||||
private bool _isCreated = false;
|
private bool _isCreated = false;
|
||||||
|
|
||||||
internal MonoObject* MonoInstance => _instance;
|
public this(ScriptClass scriptClass)
|
||||||
|
|
||||||
public UUID EntityId => _entityId;
|
|
||||||
|
|
||||||
public this(UUID entityId, ScriptClass scriptClass)
|
|
||||||
{
|
{
|
||||||
Log.EngineLogger.AssertDebug(scriptClass != null);
|
Log.EngineLogger.AssertDebug(scriptClass != null);
|
||||||
|
|
||||||
_entityId = entityId;
|
|
||||||
_scriptClass = scriptClass..AddRef();
|
_scriptClass = scriptClass..AddRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,44 +31,34 @@ class ScriptInstance : RefCounter
|
|||||||
{
|
{
|
||||||
if (_instance != null)
|
if (_instance != null)
|
||||||
{
|
{
|
||||||
InvokeOnDestroy();
|
_scriptClass.OnDestroy(_instance);
|
||||||
Mono.mono_gchandle_free(_gcHandle);
|
Mono.mono_gchandle_free(_gcHandle);
|
||||||
}
|
}
|
||||||
_scriptClass?.ReleaseRef();
|
_scriptClass?.ReleaseRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal MonoObject* MonoInstance => _instance;
|
||||||
|
|
||||||
public void Instantiate(UUID uuid)
|
public void Instantiate(UUID uuid)
|
||||||
{
|
{
|
||||||
_instance = _scriptClass.CreateInstance(uuid, let exception);
|
_instance = _scriptClass.CreateInstance(uuid);
|
||||||
_gcHandle = Mono.mono_gchandle_new(_instance, true);
|
_gcHandle = Mono.mono_gchandle_new(_instance, true);
|
||||||
|
|
||||||
if (exception != null)
|
|
||||||
ScriptEngine.HandleMonoException(exception, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InvokeOnCreate()
|
public void InvokeOnCreate()
|
||||||
{
|
{
|
||||||
_scriptClass.OnCreate(_instance, let exception);
|
_scriptClass.OnCreate(_instance);
|
||||||
_isCreated = true;
|
_isCreated = true;
|
||||||
|
|
||||||
if (exception != null)
|
|
||||||
ScriptEngine.HandleMonoException(exception, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InvokeOnUpdate(float deltaTime)
|
public void InvokeOnUpdate(float deltaTime)
|
||||||
{
|
{
|
||||||
_scriptClass.OnUpdate(_instance, deltaTime, let exception);
|
_scriptClass.OnUpdate(_instance, deltaTime);
|
||||||
|
|
||||||
if (exception != null)
|
|
||||||
ScriptEngine.HandleMonoException(exception, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InvokeOnDestroy()
|
public void InvokeOnDestroy()
|
||||||
{
|
{
|
||||||
_scriptClass.OnDestroy(_instance, let exception);
|
_scriptClass.OnDestroy(_instance);
|
||||||
|
|
||||||
if (exception != null)
|
|
||||||
ScriptEngine.HandleMonoException(exception, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public T GetFieldValue<T>(ScriptField field)
|
public T GetFieldValue<T>(ScriptField field)
|
||||||
@@ -90,22 +70,4 @@ class ScriptInstance : RefCounter
|
|||||||
{
|
{
|
||||||
_scriptClass.SetFieldValue<T>(_instance, field.[Friend]_monoField, value);
|
_scriptClass.SetFieldValue<T>(_instance, field.[Friend]_monoField, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new instance of the given component class and initializes it for the current entity.
|
|
||||||
public MonoObject* CreateComponentInstance(ScriptClass componentClassType)
|
|
||||||
{
|
|
||||||
MonoObject* componentInstance = componentClassType.CreateInstance();
|
|
||||||
|
|
||||||
// TODO: We could cache the property, but this might be fine
|
|
||||||
MonoProperty* entityProperty = Mono.mono_class_get_property_from_name(componentClassType.[Friend]_monoClass, "Entity");
|
|
||||||
|
|
||||||
MonoObject* exception = null;
|
|
||||||
|
|
||||||
Mono.mono_property_set_value(entityProperty, componentInstance, (void**)&_instance, &exception);
|
|
||||||
|
|
||||||
if (exception != null)
|
|
||||||
ScriptEngine.HandleMonoException((MonoException*)exception, this);
|
|
||||||
|
|
||||||
return componentInstance;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -509,7 +509,7 @@ namespace GlitchyEngine.World
|
|||||||
{
|
{
|
||||||
private String _scriptClassName = null;
|
private String _scriptClassName = null;
|
||||||
|
|
||||||
private ScriptInstance _instance = null;
|
private SexyScriptInstance _instance = null;
|
||||||
|
|
||||||
public StringView ScriptClassName
|
public StringView ScriptClassName
|
||||||
{
|
{
|
||||||
@@ -523,22 +523,24 @@ namespace GlitchyEngine.World
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScriptInstance Instance
|
public SexyScriptInstance Instance
|
||||||
{
|
{
|
||||||
[Inline]
|
[Inline]
|
||||||
get => _instance;
|
get => _instance;
|
||||||
[Inline]
|
[Inline]
|
||||||
set mut => SetReference!(_instance, value);
|
set mut => _instance = value;//SetReference!(_instance, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsInitialized => _instance?.IsInitialized ?? false;
|
// public bool IsInitialized => _instance?.IsInitialized ?? false;
|
||||||
|
|
||||||
public bool IsCreated => _instance?.IsCreated ?? false;
|
// public bool IsCreated => _instance?.IsCreated ?? false;
|
||||||
|
|
||||||
|
public bool IsCreated => _instance != null;
|
||||||
|
|
||||||
public void Dispose() mut
|
public void Dispose() mut
|
||||||
{
|
{
|
||||||
delete _scriptClassName;
|
delete _scriptClassName;
|
||||||
ReleaseRefAndNullify!(_instance);
|
//ReleaseRefAndNullify!(_instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,15 +100,6 @@ namespace GlitchyEngine.World
|
|||||||
ScriptEngine.InitializeInstance(targetEntity, targetComponent);
|
ScriptEngine.InitializeInstance(targetEntity, targetComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy values to entities.
|
|
||||||
// We do this in a separate loop because we might reference other entities.
|
|
||||||
// If we did it in a single loop these entities might not exist yet.
|
|
||||||
for (let (handle, script) in target._ecsWorld.Enumerate<ScriptComponent>())
|
|
||||||
{
|
|
||||||
Entity entity = .(handle, this);
|
|
||||||
ScriptEngine.CopyEditorFieldsToInstance(entity, script);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy transforms... needs special handling for the Parent<->Child relations
|
// Copy transforms... needs special handling for the Parent<->Child relations
|
||||||
for (let (sourceHandle, sourceTransform) in _ecsWorld.Enumerate<TransformComponent>())
|
for (let (sourceHandle, sourceTransform) in _ecsWorld.Enumerate<TransformComponent>())
|
||||||
{
|
{
|
||||||
@@ -269,7 +260,7 @@ namespace GlitchyEngine.World
|
|||||||
script.Instance._entity = Entity(entity, this);
|
script.Instance._entity = Entity(entity, this);
|
||||||
script.Instance.[Friend]OnCreate();
|
script.Instance.[Friend]OnCreate();
|
||||||
}
|
}
|
||||||
|
|
||||||
script.Instance.[Friend]OnUpdate(gameTime);
|
script.Instance.[Friend]OnUpdate(gameTime);
|
||||||
}
|
}
|
||||||
/*}
|
/*}
|
||||||
@@ -281,15 +272,15 @@ namespace GlitchyEngine.World
|
|||||||
{
|
{
|
||||||
if (!script.IsCreated)
|
if (!script.IsCreated)
|
||||||
{
|
{
|
||||||
if (!script.IsInitialized)
|
ScriptEngine.InitializeInstance(Entity(entity, this), script);
|
||||||
ScriptEngine.InitializeInstance(Entity(entity, this), script);
|
|
||||||
|
|
||||||
if (mode.HasFlag(.Runtime))
|
//if (mode.HasFlag(.Runtime))
|
||||||
script.Instance.InvokeOnCreate();
|
//script.Instance.InvokeOnCreate();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode.HasFlag(.Runtime))
|
if (mode.HasFlag(.Runtime) && script.Instance.ScriptClass.Methods.HasFlag(.OnUpdate))
|
||||||
script.Instance.InvokeOnUpdate(gameTime.DeltaTime);
|
ScriptEngine.InvokeOnUpdate(Entity(entity, this).UUID, gameTime.DeltaTime);
|
||||||
|
//script.Instance.InvokeOnUpdate(gameTime.DeltaTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -191,7 +191,9 @@ class SceneSerializer
|
|||||||
{
|
{
|
||||||
Serialize.Value(writer, "ScriptClass", component.ScriptClassName);
|
Serialize.Value(writer, "ScriptClass", component.ScriptClassName);
|
||||||
|
|
||||||
//if (component.HasScript)
|
ThrowUnimplemented();
|
||||||
|
|
||||||
|
/*//if (component.HasScript)
|
||||||
// TODO: Thats not a good check, I think. At least we know the script class is valid
|
// TODO: Thats not a good check, I think. At least we know the script class is valid
|
||||||
if (ScriptEngine.GetScriptClass(component.ScriptClassName) != null)
|
if (ScriptEngine.GetScriptClass(component.ScriptClassName) != null)
|
||||||
{
|
{
|
||||||
@@ -221,7 +223,7 @@ class SceneSerializer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -579,9 +581,9 @@ class SceneSerializer
|
|||||||
// But that is a bug for me to rediscover in the distant future, so in case this bug occurred and it took ages for you to
|
// But that is a bug for me to rediscover in the distant future, so in case this bug occurred and it took ages for you to
|
||||||
// figure out what happened: You are welcome :)
|
// figure out what happened: You are welcome :)
|
||||||
|
|
||||||
ScriptEngine.CreateScriptFieldMap(entity);
|
//ScriptEngine.CreateScriptFieldMap(entity);
|
||||||
|
|
||||||
var fields = ScriptEngine.GetScriptFieldMap(entity);
|
//var fields = ScriptEngine.GetScriptFieldMap(entity);
|
||||||
|
|
||||||
Try!(reader.EntryEnd());
|
Try!(reader.EntryEnd());
|
||||||
|
|
||||||
@@ -613,53 +615,47 @@ class SceneSerializer
|
|||||||
// Allocate a string on the stack, because the dictionary uses a string as key
|
// Allocate a string on the stack, because the dictionary uses a string as key
|
||||||
String fieldNameString = scope .(fieldName);
|
String fieldNameString = scope .(fieldName);
|
||||||
|
|
||||||
Result<StringView> fieldTypeName = reader.Type();
|
//if (fields.ContainsKey(fieldNameString))
|
||||||
|
//{
|
||||||
|
//var field = ref fields[fieldNameString];
|
||||||
|
|
||||||
if (fieldTypeName case .Err)
|
Result<StringView> fieldTypeName = reader.Type();
|
||||||
{
|
|
||||||
Log.EngineLogger.Error($"Failed to read field type for field \"{fieldName}\" in script \"{component.ScriptClassName}\" of entity {entity.UUID} (\"{entity.Name}\")");
|
|
||||||
reader.FileEntrySkip(1);
|
|
||||||
dontRemoveComma = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result<ScriptFieldType> fieldType = Enum.Parse<ScriptFieldType>(fieldTypeName, true);
|
/*if (fieldTypeName case .Err)
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Error($"Failed to read field type for field \"{fieldName}\" in script \"{component.ScriptClassName}\" of entity {entity.UUID} (\"{entity.Name}\")");
|
||||||
|
reader.FileEntrySkip(1);
|
||||||
|
dontRemoveComma = true;
|
||||||
|
continue;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
Result<ScriptFieldType> fieldType = Enum.Parse<ScriptFieldType>(fieldTypeName, true);
|
||||||
|
|
||||||
if ((fieldType case .Err))
|
/*if ((fieldType case .Err) || (fieldType != field.Type))
|
||||||
{
|
|
||||||
Log.EngineLogger.Error($"Error deserializing field type (Raw string: \"{fieldTypeName}\" of field: \"{fieldName}\" in script \"{component.ScriptClassName}\" of entity {entity.UUID} (\"{entity.Name}\")");
|
|
||||||
reader.FileEntrySkip(1);
|
|
||||||
dontRemoveComma = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8[sizeof(Matrix)] data = .();
|
|
||||||
|
|
||||||
if (Deserialize.Value(reader, ValueView(fieldType.Value.GetBeefType(), &data), gBonEnv) case .Err)
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Error($"Failed to deserialize data for field: \"{fieldName}\" in script \"{component.ScriptClassName}\" of entity {entity.UUID} (\"{entity.Name}\")");
|
|
||||||
reader.FileEntrySkip(1);
|
|
||||||
dontRemoveComma = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fields.ContainsKey(fieldNameString))
|
|
||||||
{
|
|
||||||
var field = ref fields[fieldNameString];
|
|
||||||
|
|
||||||
// Make sure the type we deserialized actually is correct.
|
|
||||||
if (fieldType != field.Type)
|
|
||||||
{
|
{
|
||||||
Log.EngineLogger.Error($"Unexpected field type (\"{fieldTypeName}\" instead of \"{field.Type}\" for field: \"{fieldName}\" in script \"{component.ScriptClassName}\" of entity {entity.UUID} (\"{entity.Name}\")");
|
Log.EngineLogger.Error($"Unexpected field type (\"{fieldTypeName}\" instead of \"{field.Type}\" for field: \"{fieldName}\" in script \"{component.ScriptClassName}\" of entity {entity.UUID} (\"{entity.Name}\")");
|
||||||
|
reader.FileEntrySkip(1);
|
||||||
|
dontRemoveComma = true;
|
||||||
|
continue;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//void* data = &field.[Friend]_data;
|
||||||
|
|
||||||
|
uint8[128] data;
|
||||||
|
|
||||||
|
//if (Deserialize.Value(reader, ValueView(field.Type.GetBeefType(), data), gBonEnv) case .Err)
|
||||||
|
if (Deserialize.Value(reader, ValueView(fieldType.Value.GetBeefType(), &data), gBonEnv) case .Err)
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Error($"Failed to deserialize data for field: \"{fieldName}\" in script \"{component.ScriptClassName}\" of entity {entity.UUID} (\"{entity.Name}\")");
|
||||||
|
reader.FileEntrySkip(1);
|
||||||
|
dontRemoveComma = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
/*}
|
||||||
field.SetData(data);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.EngineLogger.Error($"Script \"{component.ScriptClassName}\" doesn't have a field with name \"{fieldName}\". (Entity {entity.UUID} (\"{entity.Name}\"))");
|
Log.EngineLogger.Error($"Script \"{component.ScriptClassName}\" doesn't have a field with name \"{fieldName}\". (Entity {entity.UUID} (\"{entity.Name}\"))");
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
Try!(reader.ArrayBlockEnd());
|
Try!(reader.ArrayBlockEnd());
|
||||||
|
|||||||
+1
Submodule GlitchyEngine/vendor/NetHostBeef added at aeb099576d
Vendored
+1
-1
Submodule GlitchyEngine/vendor/imgui updated: 21c9c3225a...827764b98c
@@ -91,9 +91,6 @@ static class Mono
|
|||||||
|
|
||||||
[LinkName(.C)]
|
[LinkName(.C)]
|
||||||
public static extern MonoType* mono_class_get_type(MonoClass* monoClass);
|
public static extern MonoType* mono_class_get_type(MonoClass* monoClass);
|
||||||
|
|
||||||
[LinkName(.C)]
|
|
||||||
public static extern int32 mono_class_instance_size(MonoClass* @class);
|
|
||||||
|
|
||||||
[LinkName(.C)]
|
[LinkName(.C)]
|
||||||
public static extern char8* mono_class_get_namespace(MonoClass* monoClass);
|
public static extern char8* mono_class_get_namespace(MonoClass* monoClass);
|
||||||
@@ -161,9 +158,6 @@ static class Mono
|
|||||||
[LinkName(.C)]
|
[LinkName(.C)]
|
||||||
public static extern MonoType* mono_reflection_type_get_type(MonoReflectionType* reflectionType);
|
public static extern MonoType* mono_reflection_type_get_type(MonoReflectionType* reflectionType);
|
||||||
|
|
||||||
[LinkName(.C)]
|
|
||||||
public static extern MonoReflectionType* mono_type_get_object(MonoDomain *domain, MonoType *type);
|
|
||||||
|
|
||||||
[LinkName(.C)]
|
[LinkName(.C)]
|
||||||
public static extern MonoClassField* mono_class_get_fields(MonoClass* klass, gpointer* iter);
|
public static extern MonoClassField* mono_class_get_fields(MonoClass* klass, gpointer* iter);
|
||||||
|
|
||||||
@@ -184,9 +178,6 @@ static class Mono
|
|||||||
|
|
||||||
[LinkName(.C)]
|
[LinkName(.C)]
|
||||||
public static extern void mono_field_get_value(MonoObject* object, MonoClassField* field, void* value);
|
public static extern void mono_field_get_value(MonoObject* object, MonoClassField* field, void* value);
|
||||||
|
|
||||||
[LinkName(.C)]
|
|
||||||
public static extern void mono_field_static_get_value(MonoVTable* vt, MonoClassField* field, void* value);
|
|
||||||
|
|
||||||
/// Gets the field as object, boxes the value if it is a valuetype.
|
/// Gets the field as object, boxes the value if it is a valuetype.
|
||||||
[LinkName(.C)]
|
[LinkName(.C)]
|
||||||
@@ -238,37 +229,6 @@ static class Mono
|
|||||||
|
|
||||||
[LinkName(.C)]
|
[LinkName(.C)]
|
||||||
public static extern MonoThread* mono_thread_current();
|
public static extern MonoThread* mono_thread_current();
|
||||||
|
|
||||||
#region Property
|
|
||||||
|
|
||||||
[LinkName(.C)]
|
|
||||||
public static extern MonoProperty* mono_class_get_property_from_name(MonoClass *klass, char8* name);
|
|
||||||
|
|
||||||
[LinkName(.C)]
|
|
||||||
public static extern void mono_property_set_value(MonoProperty *prop, void *obj, void **@params, MonoObject **exc);
|
|
||||||
|
|
||||||
[LinkName(.C)]
|
|
||||||
public static extern MonoObject* mono_property_get_value(MonoProperty *prop, void *obj, void** @params, MonoObject** exc);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
[LinkName(.C)]
|
|
||||||
public static extern char8* mono_exception_get_managed_backtrace(MonoException* exc);
|
|
||||||
|
|
||||||
[LinkName(.C)]
|
|
||||||
public static extern MonoClass* mono_object_get_class(MonoObject* obj);
|
|
||||||
|
|
||||||
|
|
||||||
[LinkName(.C)]
|
|
||||||
public static extern mono_bool mono_class_is_enum(MonoClass* @class);
|
|
||||||
|
|
||||||
|
|
||||||
[LinkName(.C)]
|
|
||||||
public static extern MonoVTable* mono_class_vtable(MonoDomain* domain, MonoClass* @class);
|
|
||||||
|
|
||||||
|
|
||||||
[LinkName(.C)]
|
|
||||||
public static extern MonoObject* mono_value_box(MonoDomain* domain, MonoClass* klass, gpointer value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MonoDomain;
|
struct MonoDomain;
|
||||||
@@ -287,12 +247,8 @@ struct MonoObject;
|
|||||||
|
|
||||||
struct MonoMethod;
|
struct MonoMethod;
|
||||||
|
|
||||||
struct MonoProperty;
|
|
||||||
|
|
||||||
struct MonoThread;
|
struct MonoThread;
|
||||||
|
|
||||||
struct MonoVTable;
|
|
||||||
|
|
||||||
struct MonoException
|
struct MonoException
|
||||||
{
|
{
|
||||||
void* _bla;
|
void* _bla;
|
||||||
|
|||||||
@@ -1,2 +1,13 @@
|
|||||||
# glitchy-engine-beef
|
# glitchy-engine-beef
|
||||||
A complete refocusation, reimagination and reimplementation of the world-renowned "Glitchy Engine"
|
A complete refocusation, reimagination and reimplementation of the world-renowned "Glitchy Engine"
|
||||||
|
|
||||||
|
# Building
|
||||||
|
|
||||||
|
In order to build this repository you need the following requirements:
|
||||||
|
|
||||||
|
- Windows 10 or newer
|
||||||
|
- [Beef](https://www.beeflang.org/) (at least 0.43.5)
|
||||||
|
- Visual Studio 2022 with the Workloads: "Desktop development with C++" and ".NET desktop development" (TODO: I think it's probably possible to just install some standalone stuff, but idk...)
|
||||||
|
- TODO: I feel like I'm missing something...
|
||||||
|
|
||||||
|
If all of the requirements are met you need to run the following command in powershell (in the root directory of the repository): `./bin/prepare_dev.ps1`. This will run a script that initializes the dependencies. TODO: This script is currently not finished
|
||||||
|
|||||||
@@ -86,10 +86,10 @@ namespace Sandbox
|
|||||||
|
|
||||||
ImGui.Combo("Sampler", (.)&_sampleMode, items.Ptr, (.)items.Count);
|
ImGui.Combo("Sampler", (.)&_sampleMode, items.Ptr, (.)items.Count);
|
||||||
|
|
||||||
ImGui.SliderFloat2("Color offset and scale", ref *(float[2]*)&_colorOffset, -1.0f, 1.0f);
|
ImGui.SliderFloat2("Color offset and scale", *(float[2]*)&_colorOffset, -1.0f, 1.0f);
|
||||||
ImGui.SliderFloat2("Alpha offset and scale", ref *(float[2]*)&_alphaOffset, -1.0f, 1.0f);
|
ImGui.SliderFloat2("Alpha offset and scale", *(float[2]*)&_alphaOffset, -1.0f, 1.0f);
|
||||||
|
|
||||||
ImGui.SliderFloat2("Position", ref *(float[2]*)&_position, 2 * -Math.Max(viewedTexture.Width, viewedTexture.Height) * _zoom, 2 * Math.Max(viewedTexture.Width, viewedTexture.Height) * _zoom);
|
ImGui.SliderFloat2("Position", *(float[2]*)&_position, 2 * -Math.Max(viewedTexture.Width, viewedTexture.Height) * _zoom, 2 * Math.Max(viewedTexture.Width, viewedTexture.Height) * _zoom);
|
||||||
|
|
||||||
ImGui.BeginChild("imageChild");
|
ImGui.BeginChild("imageChild");
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,6 @@ using System;
|
|||||||
|
|
||||||
namespace GlitchyEngine.Editor;
|
namespace GlitchyEngine.Editor;
|
||||||
|
|
||||||
// TODO: Maybe rename, definitely move into different namespace
|
|
||||||
/* Why?
|
|
||||||
* - this attribute also means that the Field is being serialized
|
|
||||||
* - Editor-Namespace wont be available for distribution builds of the game
|
|
||||||
*/
|
|
||||||
[AttributeUsage(AttributeTargets.Field)]
|
|
||||||
public sealed class ShowInEditorAttribute : Attribute
|
public sealed class ShowInEditorAttribute : Attribute
|
||||||
{
|
{
|
||||||
public string DisplayName { get; set; } = null;
|
public string DisplayName { get; set; } = null;
|
||||||
|
|||||||
+5
-3
@@ -1,4 +1,5 @@
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace GlitchyEngine;
|
namespace GlitchyEngine;
|
||||||
|
|
||||||
@@ -44,7 +45,8 @@ public class Log
|
|||||||
{
|
{
|
||||||
LogMessage_Impl(LogLevel.Critical, message);
|
LogMessage_Impl(LogLevel.Critical, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
//[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
public static extern string LogMessage_Impl(LogLevel logLevel, string message);
|
[DllImport("GlitchyEditor.exe", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Log::LogMessage_Impl")]
|
||||||
|
public static extern void LogMessage_Impl(LogLevel logLevel, string message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,23 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
<BaseOutputPath></BaseOutputPath>
|
<BaseOutputPath></BaseOutputPath>
|
||||||
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
||||||
|
|
||||||
|
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||||
|
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||||
|
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<!--<DebugType>embedded</DebugType>-->
|
||||||
|
<!--<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>-->
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
<Exec Command="PowerShell ./postbuild.ps1 -sourceDir $(OutDir) -destinationDir "..\GlitchyEditor\resources\scripts"" />
|
<Exec Command="PowerShell ./postbuild.ps1 -sourceDir $(OutDir) -destinationDir "..\GlitchyEditor\resources\scripts"" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Half" Version="1.0.0" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\ScriptCoreGenerator\ScriptCoreGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
|
<ProjectReference Include="..\ScriptCoreGenerator\ScriptCoreGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -1,5 +1,18 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Net.Mime;
|
||||||
|
using System.Net.Security;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.Loader;
|
||||||
|
using System.Text;
|
||||||
using GlitchyEngine.Core;
|
using GlitchyEngine.Core;
|
||||||
using GlitchyEngine.Math;
|
using GlitchyEngine.Math;
|
||||||
|
|
||||||
@@ -74,5 +87,390 @@ internal static class ScriptGlue
|
|||||||
internal static extern float4 modf_float4(float4 x, out float4 integerPart);
|
internal static extern float4 modf_float4(float4 x, out float4 integerPart);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
private static AssemblyLoadContext? _scriptAssemblyContext;
|
||||||
|
|
||||||
|
private static Assembly? _appAssembly;
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static unsafe void LoadScriptAssembly(byte* assemblyData, long assemblyLength, byte* pdbData, long pdbLength)
|
||||||
|
{
|
||||||
|
using UnmanagedMemoryStream assemblyStream = new(assemblyData, assemblyLength);
|
||||||
|
|
||||||
|
using UnmanagedMemoryStream? pdbStream = (pdbData != null) ? new UnmanagedMemoryStream(pdbData, pdbLength) : null;
|
||||||
|
|
||||||
|
LoadAssembly(assemblyStream, pdbStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void LoadAssembly(Stream assemblyStream, Stream? pdbStream)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_scriptAssemblyContext ??= new AssemblyLoadContext("ScriptContext", true);
|
||||||
|
|
||||||
|
_appAssembly = _scriptAssemblyContext.LoadFromStream(assemblyStream, pdbStream);
|
||||||
|
|
||||||
|
Debug.Assert(_appAssembly != null);
|
||||||
|
|
||||||
|
// Test the loaded assembly
|
||||||
|
_appAssembly.GetType("Sandbox.TestClass")?.GetMethod("InternalTest")?.Invoke(null, null);
|
||||||
|
|
||||||
|
AssemblyLoadContext.EnterContextualReflection(_appAssembly);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Fehler: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static void UnloadAssemblies()
|
||||||
|
{
|
||||||
|
_scriptAssemblyContext?.Unload();
|
||||||
|
_scriptAssemblyContext = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ScriptClassInfo
|
||||||
|
{
|
||||||
|
public byte[] Name;
|
||||||
|
public Guid Guid;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NativeScriptClassInfo[]? _unsafeClasses;
|
||||||
|
|
||||||
|
struct NativeScriptClassInfo
|
||||||
|
{
|
||||||
|
public IntPtr Name;
|
||||||
|
public Guid Guid;
|
||||||
|
public ScriptMethods Methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum ScriptMethods
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
OnCreate = 0x1,
|
||||||
|
OnUpdate = 0x2,
|
||||||
|
OnDestroy = 0x4,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static unsafe void GetScriptClasses(void** outBuffer, long* length)
|
||||||
|
{
|
||||||
|
AssemblyLoadContext.EnterContextualReflection(_appAssembly);
|
||||||
|
|
||||||
|
Debug.Assert(_appAssembly != null);
|
||||||
|
|
||||||
|
Internal_FreeScriptClassNames();
|
||||||
|
|
||||||
|
var types = _appAssembly.GetTypes();
|
||||||
|
|
||||||
|
List<(string Name, Guid Guid, ScriptMethods Methods)> scriptClasses = new();
|
||||||
|
|
||||||
|
_updateMethods.Clear();
|
||||||
|
|
||||||
|
foreach (var type in types)
|
||||||
|
{
|
||||||
|
if (type.IsSubclassOf(typeof(Entity)))
|
||||||
|
{
|
||||||
|
string? name = type.FullName;
|
||||||
|
|
||||||
|
if (name == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Guid guid = type.GUID;
|
||||||
|
|
||||||
|
ScriptMethods methods = ScriptMethods.None;
|
||||||
|
|
||||||
|
MethodInfo? onUpdateMethod = type.GetMethod("OnUpdate");
|
||||||
|
if (onUpdateMethod != null)
|
||||||
|
{
|
||||||
|
_updateMethods[type] = onUpdateMethod;
|
||||||
|
|
||||||
|
methods |= ScriptMethods.OnUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
scriptClasses.Add((name, guid, methods));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_unsafeClasses = new NativeScriptClassInfo[scriptClasses.Count];
|
||||||
|
|
||||||
|
for (int i = 0; i < _unsafeClasses.Length; i++)
|
||||||
|
{
|
||||||
|
_unsafeClasses[i] = new NativeScriptClassInfo()
|
||||||
|
{
|
||||||
|
Guid = scriptClasses[i].Guid,
|
||||||
|
Name = Marshal.StringToCoTaskMemUTF8(scriptClasses[i].Name),
|
||||||
|
Methods = scriptClasses[i].Methods
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
*outBuffer = (void*)Marshal.UnsafeAddrOfPinnedArrayElement(_unsafeClasses, 0);
|
||||||
|
*length = _unsafeClasses.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static void FreeScriptClassNames()
|
||||||
|
{
|
||||||
|
Internal_FreeScriptClassNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void Internal_FreeScriptClassNames()
|
||||||
|
{
|
||||||
|
if (_unsafeClasses == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (NativeScriptClassInfo info in _unsafeClasses)
|
||||||
|
{
|
||||||
|
Marshal.FreeCoTaskMem(info.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
_unsafeClasses = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Dictionary<UUID, (Entity Entity, Type Type)> _entityScripts = new();
|
||||||
|
private static Dictionary<Type, MethodInfo> _updateMethods = new();
|
||||||
|
|
||||||
|
public struct ScriptFunctions
|
||||||
|
{
|
||||||
|
public IntPtr OnCreateMethod;
|
||||||
|
public IntPtr OnUpdateMethod;
|
||||||
|
public IntPtr OnDestroyMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define delegate with the same signature as your method
|
||||||
|
delegate void OnCreateMethodDelegate();
|
||||||
|
|
||||||
|
// Define delegate with the same signature as your method
|
||||||
|
delegate void OnUpdateMethodDelegate(float deltaTime);
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static void InvokeOnUpdate(UUID entityId, float deltaTime)
|
||||||
|
{
|
||||||
|
AssemblyLoadContext.EnterContextualReflection(_appAssembly);
|
||||||
|
|
||||||
|
Debug.Assert(_entityScripts.ContainsKey(entityId));
|
||||||
|
|
||||||
|
(Entity Entity, Type Type) entity = _entityScripts[entityId];
|
||||||
|
|
||||||
|
entity.Type.GetMethod("OnUpdate", BindingFlags.NonPublic | BindingFlags.Instance)
|
||||||
|
.Invoke(entity.Entity, new object?[]{deltaTime });
|
||||||
|
|
||||||
|
_updateMethods[entity.Type].Invoke(entity.Entity, BindingFlags.NonPublic | BindingFlags.Instance, null,
|
||||||
|
new object[] { deltaTime }, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static unsafe ScriptFunctions CreateScriptInstance(UUID entityId, byte* scriptClassName)
|
||||||
|
{
|
||||||
|
AssemblyLoadContext.EnterContextualReflection(_appAssembly);
|
||||||
|
|
||||||
|
Debug.Assert(_appAssembly != null);
|
||||||
|
|
||||||
|
string? typeName = Marshal.PtrToStringUTF8((IntPtr)scriptClassName);
|
||||||
|
|
||||||
|
Debug.Assert(typeName != null);
|
||||||
|
|
||||||
|
Type? scriptType = _appAssembly.GetType(typeName);
|
||||||
|
|
||||||
|
Debug.Assert(scriptType != null, "Script class Type not found.");
|
||||||
|
|
||||||
|
//Entity? scriptInstance = Activator.CreateInstance(scriptType, BindingFlags.Instance | BindingFlags.NonPublic, null, entityId) as Entity;
|
||||||
|
|
||||||
|
// Get the private constructor
|
||||||
|
ConstructorInfo constructor = scriptType.BaseType.GetConstructor(
|
||||||
|
BindingFlags.Instance | BindingFlags.NonPublic,
|
||||||
|
null,
|
||||||
|
new Type[] { typeof(UUID) }, // replace this with the types of your constructor parameters
|
||||||
|
null);
|
||||||
|
|
||||||
|
// Call the constructor to create an instance
|
||||||
|
Entity? scriptInstance = constructor?.Invoke(new object[] { entityId }) as Entity;
|
||||||
|
|
||||||
|
ScriptFunctions functions = new();
|
||||||
|
|
||||||
|
_entityScripts.Add(entityId, (scriptInstance!, scriptType));
|
||||||
|
|
||||||
|
//MethodInfo? onCreateMethod = scriptType.GetMethod("OnCreate", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
//if (onCreateMethod != null)
|
||||||
|
//{
|
||||||
|
// var v = MethodHelpers.GetFunctionPointerForNativeCode(onCreateMethod, null);
|
||||||
|
//}
|
||||||
|
//if (onCreateMethod != null)
|
||||||
|
//{
|
||||||
|
// //Delegate del = CreateDelegateWithTarget(onCreateMethod, scriptInstance);
|
||||||
|
|
||||||
|
// //var createDelegate = onCreateMethod.CreateDelegate<Action>(scriptInstance);
|
||||||
|
// //var createDelegate = onCreateMethod.CreateDelegate(typeof(OnCreateMethodDelegate), scriptInstance);
|
||||||
|
// //onCreateMethod.CreateDelegate(scriptInstance);
|
||||||
|
|
||||||
|
// //functions.OnCreateMethod = Marshal.GetFunctionPointerForDelegate(createDelegate);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//MethodInfo? onUpdateMethod = scriptType.GetMethod("OnUpdate", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
//if (onUpdateMethod != null)
|
||||||
|
//{
|
||||||
|
// // Create the delegate from your method and instance
|
||||||
|
// OnUpdateMethodDelegate onUpdateDelegate = (OnUpdateMethodDelegate)Delegate.CreateDelegate(typeof(OnUpdateMethodDelegate), scriptInstance, onUpdateMethod);
|
||||||
|
|
||||||
|
// // Get the function pointer from your delegate
|
||||||
|
// functions.OnUpdateMethod = Marshal.GetFunctionPointerForDelegate(onUpdateDelegate);
|
||||||
|
//}
|
||||||
|
// //functions.OnUpdateMethod = Marshal.GetFunctionPointerForDelegate((float deltaTime) => onUpdateMethod.Invoke(scriptInstance, new object?[]{ deltaTime }));
|
||||||
|
|
||||||
|
//MethodInfo? onDestroyMethod = scriptType.GetMethod("OnUpdate", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
//if (onDestroyMethod != null)
|
||||||
|
// functions.OnDestroyMethod = Marshal.GetFunctionPointerForDelegate(() => onDestroyMethod.Invoke(scriptInstance, null));
|
||||||
|
|
||||||
|
return functions;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Delegate CreateDelegate(MethodInfo method)
|
||||||
|
{
|
||||||
|
if (method == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(method));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!method.IsStatic)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("The provided method must be static.", nameof(method));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method.IsGenericMethod)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("The provided method must not be generic.", nameof(method));
|
||||||
|
}
|
||||||
|
|
||||||
|
return method.CreateDelegate(Expression.GetDelegateType(
|
||||||
|
(from parameter in method.GetParameters() select parameter.ParameterType)
|
||||||
|
.Concat(new[] { method.ReturnType })
|
||||||
|
.ToArray()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create delegate by methodinfo in target
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="method">method info</param>
|
||||||
|
/// <param name="target">A instance of the object which contains the method where will be execute</param>
|
||||||
|
/// <returns>delegate or null</returns>
|
||||||
|
public static Delegate? CreateDelegateWithTarget(MethodInfo? method, object? target)
|
||||||
|
{
|
||||||
|
if (method is null ||
|
||||||
|
target is null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
//if (method.IsStatic)
|
||||||
|
// return null;
|
||||||
|
|
||||||
|
if (method.IsGenericMethod)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return method.CreateDelegate(Expression.GetDelegateType(
|
||||||
|
(from parameter in method.GetParameters() select parameter.ParameterType)
|
||||||
|
.Concat(new[] { method.ReturnType })
|
||||||
|
.ToArray()), target);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class MethodHelpers
|
||||||
|
{
|
||||||
|
private const string DelegateTypesAssemblyName = "JitDelegateTypes";
|
||||||
|
|
||||||
|
private static ModuleBuilder _modBuilder;
|
||||||
|
|
||||||
|
private static ConcurrentDictionary<(string, object), Delegate> _delegatesCache;
|
||||||
|
private static ConcurrentDictionary<string, Type> _delegateTypesCache;
|
||||||
|
|
||||||
|
static MethodHelpers()
|
||||||
|
{
|
||||||
|
AssemblyBuilder asmBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(DelegateTypesAssemblyName), AssemblyBuilderAccess.Run);
|
||||||
|
|
||||||
|
_modBuilder = asmBuilder.DefineDynamicModule(DelegateTypesAssemblyName);
|
||||||
|
|
||||||
|
_delegatesCache = new ConcurrentDictionary<(string, object), Delegate>();
|
||||||
|
_delegateTypesCache = new ConcurrentDictionary<string, Type>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IntPtr GetFunctionPointerForNativeCode(MethodInfo meth, object instance = null)
|
||||||
|
{
|
||||||
|
string funcName = GetFullName(meth);
|
||||||
|
|
||||||
|
Delegate dlg = _delegatesCache.GetOrAdd((funcName, instance), (_) =>
|
||||||
|
{
|
||||||
|
Type[] parameters = meth.GetParameters().Select(x => x.ParameterType).ToArray();
|
||||||
|
|
||||||
|
Type delegateType = GetDelegateType(parameters, meth.ReturnType);
|
||||||
|
|
||||||
|
return Delegate.CreateDelegate(delegateType, instance, meth);
|
||||||
|
});
|
||||||
|
|
||||||
|
return Marshal.GetFunctionPointerForDelegate<Delegate>(dlg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetFullName(MethodInfo meth)
|
||||||
|
{
|
||||||
|
return $"{meth.DeclaringType.FullName}.{meth.Name}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Type GetDelegateType(Type[] parameters, Type returnType)
|
||||||
|
{
|
||||||
|
string key = GetFunctionSignatureKey(parameters, returnType);
|
||||||
|
|
||||||
|
return _delegateTypesCache.GetOrAdd(key, (_) => MakeDelegateType(parameters, returnType, key));
|
||||||
|
}
|
||||||
|
|
||||||
|
private const MethodAttributes CtorAttributes =
|
||||||
|
MethodAttributes.RTSpecialName |
|
||||||
|
MethodAttributes.HideBySig |
|
||||||
|
MethodAttributes.Public;
|
||||||
|
|
||||||
|
private const MethodImplAttributes ImplAttributes =
|
||||||
|
MethodImplAttributes.Runtime |
|
||||||
|
MethodImplAttributes.Managed;
|
||||||
|
|
||||||
|
private const MethodAttributes InvokeAttributes =
|
||||||
|
MethodAttributes.Public |
|
||||||
|
MethodAttributes.HideBySig |
|
||||||
|
MethodAttributes.NewSlot |
|
||||||
|
MethodAttributes.Virtual;
|
||||||
|
|
||||||
|
private const TypeAttributes DelegateTypeAttributes =
|
||||||
|
TypeAttributes.Class |
|
||||||
|
TypeAttributes.Public |
|
||||||
|
TypeAttributes.Sealed |
|
||||||
|
TypeAttributes.AnsiClass |
|
||||||
|
TypeAttributes.AutoClass;
|
||||||
|
|
||||||
|
private static readonly Type[] _delegateCtorSignature = { typeof(object), typeof(IntPtr) };
|
||||||
|
|
||||||
|
private static Type MakeDelegateType(Type[] parameters, Type returnType, string name)
|
||||||
|
{
|
||||||
|
TypeBuilder builder = _modBuilder.DefineType(name, DelegateTypeAttributes, typeof(MulticastDelegate));
|
||||||
|
|
||||||
|
builder.DefineConstructor(CtorAttributes, CallingConventions.Standard, _delegateCtorSignature).SetImplementationFlags(ImplAttributes);
|
||||||
|
|
||||||
|
builder.DefineMethod("Invoke", InvokeAttributes, returnType, parameters).SetImplementationFlags(ImplAttributes);
|
||||||
|
|
||||||
|
return builder.CreateTypeInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetFunctionSignatureKey(Type[] parameters, Type returnType)
|
||||||
|
{
|
||||||
|
string sig = GetTypeName(returnType);
|
||||||
|
|
||||||
|
foreach (Type type in parameters)
|
||||||
|
{
|
||||||
|
sig += '_' + GetTypeName(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sig;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetTypeName(Type type)
|
||||||
|
{
|
||||||
|
return type.FullName.Replace(".", string.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
Write-Output "Preparing repository for development..."
|
||||||
|
|
||||||
|
# Change working directory to repository root
|
||||||
|
Push-Location ($PSScriptRoot + "/..")
|
||||||
|
|
||||||
|
$RootDirectory = $(Get-Location);
|
||||||
|
|
||||||
|
# Note: When adding new scripts make sure to use "Set-Location $RootDirectory" if the script changes the working directory
|
||||||
|
|
||||||
|
# Prepare NetHost
|
||||||
|
Push-Location "GlitchyEngine/vendor/NetHostBeef"
|
||||||
|
Invoke-Expression -Command "./downloadNethost.ps1"
|
||||||
|
Pop-Location
|
||||||
|
|
||||||
|
# Return to original working directory
|
||||||
|
Pop-Location
|
||||||
Reference in New Issue
Block a user