History UI code and DTOs

This commit is contained in:
Savya Bikram Shah
2026-05-27 16:19:32 +05:45
parent df861765c2
commit 340c24cbfb
11 changed files with 143 additions and 5 deletions

View File

@@ -1,7 +1,10 @@
using System;
namespace Darkmatter.Core.Contracts.Features.History
{
public interface IUndoStack
{
event Action OnStackChanged;
bool CanUndo { get; }
bool CanRedo { get; }
void Push(ICommand cmd); // executes + appends

View File

@@ -0,0 +1,18 @@
using System.Collections.Generic;
using Darkmatter.Core.Contracts.Features.Drawing;
using Darkmatter.Core.Data.Dynamic.Features.Coloring;
using UnityEngine;
namespace Darkmatter.Core.Data.Static.Features.Drawing
{
[CreateAssetMenu(menuName = "Darkmatter/Drawing/New Drawing Template")]
public class DrawingTemplateSO : ScriptableObject, IDrawingTemplate
{
[field: SerializeField] public string Id { get; private set; }
[field: SerializeField] public string DisplayName { get; private set; }
[field: SerializeField] public Sprite DefaultThumbnail { get; private set; }
[field: SerializeField] public Sprite PaperBackground { get; private set; }
[field: SerializeField] public IReadOnlyList<ShapeSO> Pieces { get; private set; }
[field: SerializeField] public IReadOnlyList<ColorRegionDTO> Regions { get; private set; }
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 712e4ea76c27b4cdaab50081d36d953a

View File

@@ -5,7 +5,5 @@ namespace Darkmatter.Core.Enums.Services.Scenes
Boot,
MainMenu,
Gameplay,
TestTraffic,
VehicleTest,
}
}

View File

@@ -2,14 +2,20 @@ using Darkmatter.Core.Contracts.Features.History;
using Darkmatter.Libs.Installers;
using UnityEngine;
using VContainer;
using VContainer.Unity;
namespace Darkmatter.Features.History
{
public class HistoryServiceModule : MonoBehaviour,IServiceModule
public class HistoryServiceModule : MonoBehaviour, IServiceModule
{
[SerializeField] private HistoryButtonsView historyButtonsView;
public void Register(IContainerBuilder builder)
{
builder.Register<IUndoStack, UndoStack>(Lifetime.Singleton);
if (historyButtonsView != null)
builder.RegisterEntryPoint<HistoryButtonsPresenter>().WithParameter(historyButtonsView);
}
}
}
}

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using Darkmatter.Core.Contracts.Features.History;
@@ -10,6 +11,7 @@ namespace Darkmatter.Features.History
private readonly LinkedList<ICommand> _undo = new();
private readonly Stack<ICommand> _redo = new();
public event Action OnStackChanged;
public bool CanUndo => _undo.Count > 0;
public bool CanRedo => _redo.Count > 0;
@@ -17,8 +19,9 @@ namespace Darkmatter.Features.History
{
cmd.Execute();
_undo.AddLast(cmd);
if (_undo.Count > Capacity) _undo.RemoveFirst();
if (_undo.Count > Capacity) _undo.RemoveFirst();
_redo.Clear();
OnStackChanged?.Invoke();
}
public void Undo()
@@ -28,6 +31,7 @@ namespace Darkmatter.Features.History
_undo.RemoveLast();
cmd.Undo();
_redo.Push(cmd);
OnStackChanged?.Invoke();
}
public void Redo()
@@ -36,12 +40,15 @@ namespace Darkmatter.Features.History
var cmd = _redo.Pop();
cmd.Execute();
_undo.AddLast(cmd);
OnStackChanged?.Invoke();
}
public void Clear()
{
foreach (var cmd in _undo) cmd.Undo();
_undo.Clear();
_redo.Clear();
OnStackChanged?.Invoke();
}
}
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 659176aa2d382465cbb2c6bc8446d655
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,57 @@
using System;
using Darkmatter.Core.Contracts.Features.History;
using VContainer.Unity;
namespace Darkmatter.Features.History
{
public class HistoryButtonsPresenter : IStartable, IDisposable
{
private readonly HistoryButtonsView _view;
private readonly IUndoStack _undoStack;
public HistoryButtonsPresenter(IUndoStack undoStack, HistoryButtonsView view)
{
_undoStack = undoStack;
_view = view;
}
public void Start()
{
_view.OnUndoClicked += HandleUndoClicked;
_view.OnRedoClicked += HandleRedoClicked;
_view.OnClearClicked += HandleClearClicked;
UpdateButtonUI();
_undoStack.OnStackChanged += UpdateButtonUI;
}
private void HandleClearClicked()
{
_undoStack.Clear();
}
private void HandleRedoClicked()
{
_undoStack.Redo();
}
private void HandleUndoClicked()
{
_undoStack.Undo();
}
private void UpdateButtonUI()
{
_view.SetUndoInteractable(_undoStack.CanUndo);
_view.SetRedoInteractable(_undoStack.CanRedo);
_view.SetClearInteractable(_undoStack.CanUndo || _undoStack.CanRedo);
}
public void Dispose()
{
_view.OnUndoClicked -= HandleUndoClicked;
_view.OnRedoClicked -= HandleRedoClicked;
_view.OnClearClicked -= HandleClearClicked;
_undoStack.OnStackChanged -= UpdateButtonUI;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 57867eec53ed04b9a93f0fd65639c98e

View File

@@ -0,0 +1,35 @@
using System;
using UnityEngine;
using UnityEngine.UI;
namespace Darkmatter.Features.History
{
public class HistoryButtonsView : MonoBehaviour
{
[SerializeField] private Button undoButton;
[SerializeField] private Button redoButton;
[SerializeField] private Button clearButton;
public event System.Action OnUndoClicked;
public event System.Action OnRedoClicked;
public event System.Action OnClearClicked;
void Start()
{
undoButton.onClick.AddListener(() => OnUndoClicked?.Invoke());
redoButton.onClick.AddListener(() => OnRedoClicked?.Invoke());
clearButton.onClick.AddListener(() => OnClearClicked?.Invoke());
}
public void SetUndoInteractable(bool value) => undoButton.interactable = value;
public void SetRedoInteractable(bool value) => redoButton.interactable = value;
public void SetClearInteractable(bool value) => clearButton.interactable = value;
private void OnDestroy()
{
undoButton.onClick.RemoveListener(() => OnUndoClicked?.Invoke());
redoButton.onClick.RemoveListener(() => OnRedoClicked?.Invoke());
clearButton.onClick.RemoveListener(() => OnClearClicked?.Invoke());
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 5b5751e64fe1947f3b800001d995f817