mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 21:01:52 +00:00
Show Buttons in entity editor
- ScriptEngine: Added HasCustomAttribute- extension method - ScriptEngine: Added Application class
This commit is contained in:
@@ -110,6 +110,8 @@ namespace GlitchyEditor
|
|||||||
{
|
{
|
||||||
Application.Get().Window.IsVSync = true;
|
Application.Get().Window.IsVSync = true;
|
||||||
|
|
||||||
|
ScriptEngine.ApplicationInfo.IsEditor = true;
|
||||||
|
|
||||||
_contentManager = contentManager;
|
_contentManager = contentManager;
|
||||||
|
|
||||||
InitGraphics();
|
InitGraphics();
|
||||||
@@ -871,6 +873,8 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
using (Scene runtimeScene = new Scene())
|
using (Scene runtimeScene = new Scene())
|
||||||
{
|
{
|
||||||
|
ScriptEngine.ApplicationInfo.IsInPlayMode = true;
|
||||||
|
|
||||||
_editorScene.CopyTo(runtimeScene, true);
|
_editorScene.CopyTo(runtimeScene, true);
|
||||||
|
|
||||||
SetActiveScene(runtimeScene, startRuntime: true, startSimulation: true);
|
SetActiveScene(runtimeScene, startRuntime: true, startSimulation: true);
|
||||||
@@ -951,6 +955,8 @@ namespace GlitchyEditor
|
|||||||
/// Stops the simulation or game and returns to edit mode.
|
/// Stops the simulation or game and returns to edit mode.
|
||||||
private void OnSceneStop()
|
private void OnSceneStop()
|
||||||
{
|
{
|
||||||
|
ScriptEngine.ApplicationInfo.IsInEditMode = true;
|
||||||
|
|
||||||
SetActiveScene(_editorScene, startRuntime: true, startSimulation: false);
|
SetActiveScene(_editorScene, startRuntime: true, startSimulation: false);
|
||||||
|
|
||||||
// TODO: _editorScene.DeserializeScripts(scriptData);
|
// TODO: _editorScene.DeserializeScripts(scriptData);
|
||||||
|
|||||||
@@ -113,6 +113,68 @@ static class ScriptEngine
|
|||||||
internal static MonoClass* s_RunInEditModeAttribute;
|
internal static MonoClass* s_RunInEditModeAttribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ApplicationData
|
||||||
|
{
|
||||||
|
private bool _isEditor;
|
||||||
|
private bool _isPlayer;
|
||||||
|
|
||||||
|
private bool _isInEditMode;
|
||||||
|
private bool _isInPlayMode;
|
||||||
|
|
||||||
|
public bool IsEditor
|
||||||
|
{
|
||||||
|
get => _isEditor;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_isEditor = value;
|
||||||
|
|
||||||
|
if (_isEditor)
|
||||||
|
_isPlayer = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsPlayer
|
||||||
|
{
|
||||||
|
get => _isPlayer;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_isPlayer = value;
|
||||||
|
|
||||||
|
if (_isPlayer)
|
||||||
|
_isEditor = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsInEditMode
|
||||||
|
{
|
||||||
|
get => _isInEditMode;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_isInEditMode = value;
|
||||||
|
|
||||||
|
if (_isInEditMode)
|
||||||
|
_isInPlayMode = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsInPlayMode
|
||||||
|
{
|
||||||
|
get => _isInPlayMode;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_isInPlayMode = value;
|
||||||
|
|
||||||
|
if (_isInPlayMode)
|
||||||
|
_isInEditMode = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ApplicationData _applicationData = new ApplicationData() ~ delete _;
|
||||||
|
|
||||||
|
/// Contains information about the application context
|
||||||
|
public static ApplicationData ApplicationInfo => _applicationData;
|
||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
{
|
||||||
InitMono();
|
InitMono();
|
||||||
|
|||||||
@@ -475,9 +475,31 @@ static class ScriptGlue
|
|||||||
id = UUID.Create();
|
id = UUID.Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Editor Stuff
|
#region Application
|
||||||
|
|
||||||
|
[RegisterCall("ScriptGlue::Application_IsEditor")]
|
||||||
|
static bool Application_IsEditor()
|
||||||
|
{
|
||||||
|
return ScriptEngine.ApplicationInfo.IsEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
[RegisterCall("ScriptGlue::Application_IsPlayer")]
|
||||||
|
static bool Application_IsPlayer()
|
||||||
|
{
|
||||||
|
return ScriptEngine.ApplicationInfo.IsPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
[RegisterCall("ScriptGlue::Application_IsInEditMode")]
|
||||||
|
static bool Application_IsInEditMode()
|
||||||
|
{
|
||||||
|
return ScriptEngine.ApplicationInfo.IsInEditMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
[RegisterCall("ScriptGlue::Application_IsInPlayMode")]
|
||||||
|
static bool Application_IsInPlayMode()
|
||||||
|
{
|
||||||
|
return ScriptEngine.ApplicationInfo.IsInPlayMode;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@@ -202,14 +202,6 @@ namespace GlitchyEngine.World
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Start(bool simulation, bool runtime)
|
|
||||||
{
|
|
||||||
if (simulation)
|
|
||||||
StartSimulation();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StartRuntime()
|
public void StartRuntime()
|
||||||
{
|
{
|
||||||
ScriptEngine.StartRuntime(this);
|
ScriptEngine.StartRuntime(this);
|
||||||
|
|||||||
@@ -1,15 +1,37 @@
|
|||||||
namespace GlitchyEngine.Core;
|
namespace GlitchyEngine.Core;
|
||||||
|
|
||||||
public class Application
|
/// <summary>
|
||||||
|
/// Contains information about the application runtime and methods to control it.
|
||||||
|
/// </summary>
|
||||||
|
public static class Application
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true when the script is running in edit mode.
|
/// Returns <see langword="true"/> when the application is running in the editor (any mode e.g. edit mode or play mode).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <seealso cref="IsPlaying"/>
|
/// <seealso cref="IsPlayer"/>
|
||||||
public bool IsEditor = false;
|
/// <seealso cref="IsInEditMode"/>
|
||||||
|
/// <seealso cref="IsInPlayMode"/>
|
||||||
|
public static bool IsEditor => ScriptGlue.Application_IsEditor();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true when the script is running in play mode or in the player.
|
/// Returns <see langword="true"/> when the application is running in the dedicated player.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <seealso cref="IsEditor"/>
|
/// <seealso cref="IsEditor"/>
|
||||||
public bool IsPlaying = false;
|
public static bool IsPlayer => ScriptGlue.Application_IsPlayer();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns <see langword="true"/> when the application is running in the editor and the editor is in edit mode.<br/>
|
||||||
|
/// If <see cref="IsEditor"/> is <see langword="false"/> (i.e. the application is not running in the editor), <see cref="IsInEditMode"/> will always be <see langword="false"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="IsEditor"/>
|
||||||
|
/// <seealso cref="IsInPlayMode"/>
|
||||||
|
public static bool IsInEditMode => ScriptGlue.Application_IsInEditMode();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns <see langword="true"/> when the application is running in the editor (<see cref="IsEditor"/> = <see langword="true"/>) and the editor is in play mode. Or when the application in running in the dedicated player (<see cref="IsPlayer"/> = <see langword="true"/>)<br/>
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="IsEditor"/>
|
||||||
|
/// <seealso cref="IsPlayer"/>
|
||||||
|
/// <seealso cref="IsInEditMode"/>
|
||||||
|
public static bool IsInPlayMode => ScriptGlue.Application_IsInPlayMode();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace GlitchyEngine.Core;
|
namespace GlitchyEngine.Core;
|
||||||
|
|
||||||
public abstract class EngineObject
|
public abstract class EngineObject
|
||||||
|
|||||||
@@ -24,11 +24,16 @@ internal class EntityEditor
|
|||||||
public static bool ShowFieldInEditor(FieldInfo fieldInfo)
|
public static bool ShowFieldInEditor(FieldInfo fieldInfo)
|
||||||
{
|
{
|
||||||
if (fieldInfo.IsPublic)
|
if (fieldInfo.IsPublic)
|
||||||
|
{
|
||||||
|
// Public fields are visible by default (No HideInEditorAttribute)
|
||||||
|
if (fieldInfo.HasCustomAttribute<HideInEditorAttribute>())
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
var showInEditorAttribute = fieldInfo.GetCustomAttribute<ShowInEditorAttribute>();
|
// Private, protected and internal fields are hidden by default (No ShowInEditorAttribute)
|
||||||
|
if (fieldInfo.HasCustomAttribute<ShowInEditorAttribute>())
|
||||||
if (showInEditorAttribute != null)
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -357,13 +362,9 @@ internal class EntityEditor
|
|||||||
|
|
||||||
public static void ShowEditor(Type type, object reference)
|
public static void ShowEditor(Type type, object reference)
|
||||||
{
|
{
|
||||||
T GetValue<T>(FieldInfo fieldInfo)
|
|
||||||
{
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
// Iterate all fields
|
||||||
foreach (FieldInfo field in type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
|
foreach (FieldInfo field in type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
@@ -371,8 +372,6 @@ internal class EntityEditor
|
|||||||
|
|
||||||
if (ShowFieldInEditor(field))
|
if (ShowFieldInEditor(field))
|
||||||
{
|
{
|
||||||
//Log.Info(field.Name);
|
|
||||||
|
|
||||||
object value = field.GetValue(reference);
|
object value = field.GetValue(reference);
|
||||||
|
|
||||||
IEnumerable<Attribute> attributes = field.GetCustomAttributes();
|
IEnumerable<Attribute> attributes = field.GetCustomAttributes();
|
||||||
@@ -388,6 +387,35 @@ internal class EntityEditor
|
|||||||
|
|
||||||
ImGui.PopID();
|
ImGui.PopID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Iterate all methods
|
||||||
|
foreach (MethodInfo method in type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
|
||||||
|
{
|
||||||
|
var showButton = method.GetCustomAttribute<ShowButtonAttribute>();
|
||||||
|
|
||||||
|
if (showButton == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (Application.IsInEditMode && !showButton.Visibility.HasFlag(ButtonVisibility.InEditMode))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (Application.IsInPlayMode && !showButton.Visibility.HasFlag(ButtonVisibility.InPlayMode))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
ImGui.PushID(i);
|
||||||
|
|
||||||
|
if (method.GetParameters().Length > 0)
|
||||||
|
{
|
||||||
|
Log.Error($"Method {method.Name} cannot be executed from editor, because it expects arguments.");
|
||||||
|
}
|
||||||
|
else if (ImGui.Button(showButton.ButtonText))
|
||||||
|
{
|
||||||
|
method.Invoke(reference, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.PopID();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ListPayload
|
struct ListPayload
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Editor;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies, that the field should not be visible in the editor.
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Field)]
|
||||||
|
public sealed class HideInEditorAttribute : Attribute
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Editor;
|
||||||
|
|
||||||
|
public enum ButtonVisibility
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The button will be visible in edit mode.
|
||||||
|
/// </summary>
|
||||||
|
InEditMode = 1,
|
||||||
|
/// <summary>
|
||||||
|
/// The button will be visible in play mode.
|
||||||
|
/// </summary>
|
||||||
|
InPlayMode = 2,
|
||||||
|
/// <summary>
|
||||||
|
/// The button will always be visible.
|
||||||
|
/// </summary>
|
||||||
|
Always = InEditMode | InPlayMode
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies that a button will be shown in the editor that, when clicked, executes the method this attribute is attached to.
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Method)]
|
||||||
|
public sealed class ShowButtonAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The text on the button.
|
||||||
|
/// </summary>
|
||||||
|
public string ButtonText { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the button is visible in edit and/or play mode.
|
||||||
|
/// </summary>
|
||||||
|
public ButtonVisibility Visibility { get; set; } = ButtonVisibility.Always;
|
||||||
|
|
||||||
|
public ShowButtonAttribute(string buttonText)
|
||||||
|
{
|
||||||
|
ButtonText = buttonText;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,11 +7,16 @@ namespace GlitchyEngine.Editor;
|
|||||||
* - this attribute also means that the Field is being serialized
|
* - this attribute also means that the Field is being serialized
|
||||||
* - Editor-Namespace wont be available for distribution builds of the game
|
* - Editor-Namespace wont be available for distribution builds of the game
|
||||||
*/
|
*/
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies that the field should be visible in the editor, regardless of it's code visibility (private, protected, etc...)
|
||||||
|
/// If this attribute is specified, the field will also be serialized.
|
||||||
|
/// </summary>
|
||||||
[AttributeUsage(AttributeTargets.Field)]
|
[AttributeUsage(AttributeTargets.Field)]
|
||||||
public sealed class ShowInEditorAttribute : Attribute
|
public sealed class ShowInEditorAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The label with which the field will be shown in the editor.
|
||||||
|
/// If not specified, the fields name will be used.
|
||||||
|
/// </summary>
|
||||||
public string DisplayName { get; set; } = null;
|
public string DisplayName { get; set; } = null;
|
||||||
|
|
||||||
public ShowInEditorAttribute()
|
|
||||||
{}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Extensions;
|
||||||
|
|
||||||
|
public static class FieldInfoExtension
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns <see langword="true"/> if the field has the specified attribute.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of the attribte.</typeparam>
|
||||||
|
public static bool HasCustomAttribute<T>(this FieldInfo fiedInfo) where T : Attribute
|
||||||
|
{
|
||||||
|
return fiedInfo.GetCustomAttribute<T>() != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -120,14 +120,19 @@ internal static class ScriptGlue
|
|||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
internal static extern void UUID_CreateNew(out UUID uuid);
|
internal static extern void UUID_CreateNew(out UUID uuid);
|
||||||
|
|
||||||
#region Application
|
#region Application
|
||||||
|
|
||||||
// TODO: Implement IsEditor and IsPlaying
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
//[MethodImpl(MethodImplOptions.InternalCall)]
|
internal static extern bool Application_IsEditor();
|
||||||
//internal static extern bool Application_IsEditor();
|
|
||||||
|
|
||||||
//[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
//internal static extern bool Application_IsPlaying();
|
internal static extern bool Application_IsPlayer();
|
||||||
|
|
||||||
#endregion
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
|
internal static extern bool Application_IsInEditMode();
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
|
internal static extern bool Application_IsInPlayMode();
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user