Skip to content

Commit

Permalink
Start implementing timeline editor for sprite...
Browse files Browse the repository at this point in the history
  • Loading branch information
isadorasophia committed Dec 16, 2023
1 parent aab51bb commit cd4e615
Show file tree
Hide file tree
Showing 13 changed files with 146 additions and 21 deletions.
8 changes: 8 additions & 0 deletions src/Murder.Editor/Components/CustomTimeComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Bang.Components;

namespace Murder.Editor.Components
{
internal readonly struct CustomTimeComponent : IComponent
{
}
}
6 changes: 4 additions & 2 deletions src/Murder.Editor/Components/EditorComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ namespace Murder.Editor.Components
[DoNotPersistOnSave]
public struct EditorComponent : IModifiableComponent
{
public readonly EditorHook EditorHook = new();
public readonly EditorHook EditorHook;

public EditorComponent() { }
public EditorComponent() => EditorHook = new();

public EditorComponent(EditorHook? hook) => EditorHook = hook ?? new();

public void Subscribe(Action notification) { }

Expand Down
20 changes: 20 additions & 0 deletions src/Murder.Editor/Components/TimelineEditorComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Bang.Components;
using Murder.Attributes;
using Murder.Editor.Utilities;
using Murder.Utilities.Attributes;

namespace Murder.Editor.Components
{
[RuntimeOnly]
[DoNotPersistOnSave]
internal class TimelineEditorComponent : IComponent
{
public readonly TimelineEditorHook Hook = new();

public TimelineEditorComponent() { }

public void Subscribe(Action _) { }

public void Unsubscribe(Action _) { }
}
}
44 changes: 39 additions & 5 deletions src/Murder.Editor/CustomEditors/SpriteEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@
using Murder.Editor.ImGuiExtended;
using Murder.Editor.Stages;
using Murder.Editor.Systems;
using Murder.Editor.Utilities;
using Murder.Editor.Utilities.Attributes;
using Murder.Utilities;
using System.Numerics;
using System.Text;

namespace Murder.Editor.CustomEditors
{
Expand All @@ -38,7 +41,7 @@ public override void OpenEditor(ImGuiRenderer imGuiRenderer, RenderContext rende

if (!ActiveEditors.ContainsKey(_sprite.Guid))
{
Stage stage = new(imGuiRenderer, renderContext);
Stage stage = new(imGuiRenderer, renderContext, hook: new TimelineEditorHook());

SpriteInformation info = new(stage);
ActiveEditors[_sprite.Guid] = info;
Expand All @@ -51,6 +54,7 @@ private void InitializeStage(Stage stage, SpriteInformation info)
{
GameLogger.Verify(_sprite is not null);

stage.ActivateSystemsWith(enable: true, typeof(SpriteEditorAttribute));
stage.ToggleSystem(typeof(EntitiesSelectorSystem), false);

IEnumerable<string> animations = _sprite.Animations.Keys;
Expand All @@ -63,7 +67,7 @@ private void InitializeStage(Stage stage, SpriteInformation info)

stage.ShowInfo = false;
stage.EditorHook.DrawSelection = false;
stage.EditorHook.CurrentZoomLevel = 5;
stage.EditorHook.CurrentZoomLevel = 6;
}

public override void DrawEditor()
Expand Down Expand Up @@ -269,12 +273,40 @@ private void DrawTimeline(SpriteInformation info)
{
if (_sprite.Animations.TryGetValue(info.SelectedAnimation, out Animation selectedAnimation))
{
if (ImGui.Button(""))
if (Game.Instance.IsPaused && ImGui.Button("\uf04b"))
{
Game.Instance.Resume();
}
else if (!Game.Instance.IsPaused && ImGui.Button("\uf04c"))
{
Game.Instance.Pause();
}

ImGui.SameLine();

StringBuilder text = new();
if (string.IsNullOrEmpty(info.SelectedAnimation))
{
text.Append("Default animation");
}
else
{
text.Append($"\"{info.SelectedAnimation}\"");
}

if (selectedAnimation.Events.Count == 0)
{
text.Append(" | 0 events");
}
else
{
text.Append($" | {selectedAnimation.Events.Count} event{(selectedAnimation.Events.Count > 1 ? "s" : "")}");
}

text.Append($" | {selectedAnimation.AnimationDuration}s");

ImGui.Text($"{info.SelectedAnimation}, {selectedAnimation.Events.Count} event{(selectedAnimation.Events.Count > 1 ? "s" : "")}, {selectedAnimation.AnimationDuration}s duration");
ImGui.TextColored(Game.Profile.Theme.Faded, text.ToString());

if (ImGui.BeginChild("Timeline"))
{
Vector2 position = ImGui.GetItemRectMin();
Expand Down Expand Up @@ -338,7 +370,7 @@ private void DrawTimeline(SpriteInformation info)
}
}

float rate = info.AnimationProgress;
float rate = (info.Hook.TimeSinceAnimationStarted % selectedAnimation.AnimationDuration) / selectedAnimation.AnimationDuration;

Vector2 arrowPosition = position + new Vector2(padding * 3 + (area.X - padding * 5) * rate, 0);
drawList.AddTriangleFilled(arrowPosition + new Vector2(-6, 0), arrowPosition + new Vector2(6, 0), arrowPosition + new Vector2(0, 20), arrowColor);
Expand Down Expand Up @@ -390,6 +422,8 @@ protected record SpriteInformation(Stage Stage)
/// </summary>
public float AnimationProgress = 0;

public TimelineEditorHook Hook => (TimelineEditorHook)Stage.EditorHook;

public SoundEventId SoundTest = new();

[Tooltip("This will create a sound to test in this editor. The actual sound must be added to the entity!")]
Expand Down
9 changes: 6 additions & 3 deletions src/Murder.Editor/Stage/Stage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,17 @@ public partial class Stage : IDisposable

public bool ShowInfo { get; set; } = true;

public Stage(ImGuiRenderer imGuiRenderer, RenderContext renderContext, Guid? worldGuid = null)
public Stage(ImGuiRenderer imGuiRenderer, RenderContext renderContext, Guid? worldGuid = null) :
this(imGuiRenderer, renderContext, hook: new(), worldGuid) { }

public Stage(ImGuiRenderer imGuiRenderer, RenderContext renderContext, EditorHook hook, Guid? worldGuid = null)
{
_imGuiRenderer = imGuiRenderer;
_renderContext = renderContext;

_world = new MonoWorld(StageHelpers.FetchEditorSystems(), _renderContext.Camera, worldGuid ?? Guid.Empty);

EditorComponent editorComponent = new();
EditorComponent editorComponent = new(hook);

EditorHook = editorComponent.EditorHook;

Expand All @@ -58,7 +61,7 @@ public Stage(ImGuiRenderer imGuiRenderer, RenderContext renderContext, Guid? wor

_world.AddEntity(editorComponent);
}

private void InitializeDrawAndWorld()
{
_calledStart = true;
Expand Down
33 changes: 33 additions & 0 deletions src/Murder.Editor/Systems/Editor/TimelineSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Bang.Contexts;
using Bang.Entities;
using Bang.Systems;
using Murder.Components;
using Murder.Editor.Components;
using Murder.Editor.Utilities;
using Murder.Editor.Utilities.Attributes;

namespace Murder.Editor.Systems.Editor;

[SpriteEditor]
[Filter(typeof(EditorComponent))]
internal class TimelineSystem : IUpdateSystem
{
public void Update(Context context)
{
if (!context.HasAnyEntity ||
context.Entity.TryGetComponent<EditorComponent>() is not EditorComponent component ||
component.EditorHook is not TimelineEditorHook hook)
{
return;
}

if (context.World.GetEntitiesWith(typeof(SpriteComponent)).FirstOrDefault() is not Entity entity)
{
return;
}

SpriteComponent sprite = entity.GetSprite();

hook.TimeSinceAnimationStarted = Game.Now - sprite.AnimationStartedTime;
}
}
4 changes: 2 additions & 2 deletions src/Murder.Editor/Systems/SpriteRenderDebugSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ public void Draw(RenderContext render, Context context)
Color = baseColor,
Outline = e.HasComponent<IsSelectedComponent>() ? Color.White.FadeAlpha(0.65f) : null,
},
new AnimationInfo(animationId, start));
new AnimationInfo(animationId, start) with { UseScaledTime = true });

if (frameInfo.Complete && overload != null)
{
Expand Down Expand Up @@ -224,7 +224,7 @@ public void Draw(RenderContext render, Context context)
Color = baseColor * reflection.Alpha,
Scale = scale * new Vector2(1, -1),
},
new AnimationInfo(animationId, start));
new AnimationInfo(animationId, start) with { UseScaledTime = true });
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Murder.Editor.Utilities.Attributes
namespace Murder.Editor.Utilities.Attributes
{
public class DialogueEditorAttribute : Attribute
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Murder.Editor.Utilities.Attributes
{
public class SpriteEditorAttribute : Attribute
{
}
}
File renamed without changes.
6 changes: 6 additions & 0 deletions src/Murder.Editor/Utilities/Stage/TimelineEditorHook.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Murder.Editor.Utilities;

internal class TimelineEditorHook : EditorHook
{
public float TimeSinceAnimationStarted = 0;
}
22 changes: 21 additions & 1 deletion src/Murder.Editor/Utilities/StageHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Murder.Editor.Attributes;
using Murder.Editor.CustomEditors;
using Murder.Editor.Data.Graphics;
using Murder.Editor.Utilities.Attributes;
using Murder.Prefabs;
using System.Collections.Immutable;
using System.Reflection;
Expand Down Expand Up @@ -137,6 +138,26 @@ internal static class StageHelpers
}
}

// I am aware that we should be generalizing this already. But hear me out: I can do this later...
foreach (Type t in ReflectionHelper.GetAllTypesWithAttributeDefinedOfType<SpriteEditorAttribute>(typeof(ISystem)))
{
if (systemsAdded.Contains(t))
{
// Already added, so skip.
continue;
}

if (Activator.CreateInstance(t) is ISystem system)
{
systems.Add((system, /* isActive */ false));
systemsAdded.Add(t);
}
else
{
GameLogger.Error($"The {t} is not a valid system!");
}
}

foreach (Type t in ReflectionHelper.GetAllTypesWithAttributeDefinedOfType<DefaultEditorSystemAttribute>(typeof(ISystem)))
{
if (systemsAdded.Contains(t))
Expand All @@ -159,7 +180,6 @@ internal static class StageHelpers
}
}


return systems;
}

Expand Down
1 change: 0 additions & 1 deletion src/Murder/Components/Graphics/SpriteComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using Murder.Utilities.Attributes;
using System.Collections.Immutable;
using System.Numerics;
using System.Text.Json.Serialization;

namespace Murder.Components
{
Expand Down

0 comments on commit cd4e615

Please sign in to comment.