mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-05-24 06:46:26 -04:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
178 lines
4.1 KiB
C#
178 lines
4.1 KiB
C#
using System.Collections;
|
|
using Sandbox.MovieMaker;
|
|
|
|
namespace Editor.MovieMaker;
|
|
|
|
#nullable enable
|
|
|
|
public interface IHistoryItem
|
|
{
|
|
int Index { get; }
|
|
string Title { get; }
|
|
string Icon { get; }
|
|
DateTime Time { get; }
|
|
|
|
bool Apply();
|
|
}
|
|
|
|
public interface IHistoryScope : IDisposable
|
|
{
|
|
void PostChange();
|
|
void IDisposable.Dispose() => PostChange();
|
|
}
|
|
|
|
public sealed class SessionHistory : IReadOnlyList<IHistoryItem>
|
|
{
|
|
private readonly Session _session;
|
|
|
|
private sealed class HistoryItem : IHistoryItem, IHistoryScope
|
|
{
|
|
private readonly SessionHistory _history;
|
|
|
|
public int Index { get; }
|
|
public string Title { get; }
|
|
public string Icon { get; }
|
|
|
|
public DateTime Time { get; private set; }
|
|
public SessionSnapshot Snapshot { get; private set; }
|
|
|
|
public HistoryItem( SessionHistory history, int index, string title, string icon, DateTime time, SessionSnapshot snapshot )
|
|
{
|
|
_history = history;
|
|
|
|
Index = index;
|
|
Title = title;
|
|
Icon = icon;
|
|
Time = time;
|
|
|
|
Snapshot = snapshot;
|
|
}
|
|
|
|
public bool Apply()
|
|
{
|
|
_history._index = Index;
|
|
|
|
return _history._session.Restore( Snapshot );
|
|
}
|
|
|
|
public void PostChange()
|
|
{
|
|
if ( _history.Index != Index )
|
|
{
|
|
Log.Warning( "Trying to change a closed history scope." );
|
|
return;
|
|
}
|
|
|
|
Time = DateTime.UtcNow;
|
|
Snapshot = _history._session.Snapshot();
|
|
}
|
|
|
|
public override string ToString() => Title;
|
|
}
|
|
|
|
private readonly List<HistoryItem> _items = new();
|
|
private int _index;
|
|
|
|
public bool CanUndo => Previous is not null;
|
|
public bool CanRedo => Next is not null;
|
|
|
|
public int Count => _items.Count;
|
|
public int Index => _index;
|
|
|
|
public IHistoryItem? Previous => _index > 0 ? _items[_index - 1] : null;
|
|
public IHistoryItem Current => _items[_index];
|
|
public IHistoryItem? Next => _index < _items.Count - 1 ? _items[_index + 1] : null;
|
|
|
|
public SessionHistory( Session session )
|
|
{
|
|
_session = session;
|
|
}
|
|
|
|
internal void Initialize()
|
|
{
|
|
if ( _items.Count == 0 )
|
|
{
|
|
_items.Add( new HistoryItem( this, 0, "Loaded Project", "file_open", DateTime.UtcNow, _session.Snapshot() ) );
|
|
}
|
|
}
|
|
|
|
public IHistoryScope Push( string title )
|
|
{
|
|
var before = _items[_index].Snapshot;
|
|
var item = new HistoryItem( this, ++_index, title, _session.EditMode?.Type.Icon ?? "edit", DateTime.UtcNow, before );
|
|
|
|
_items.RemoveRange( _index, _items.Count - _index );
|
|
_items.Add( item );
|
|
|
|
return item;
|
|
}
|
|
|
|
public bool Undo() => Previous?.Apply() ?? false;
|
|
public bool Redo() => Next?.Apply() ?? false;
|
|
|
|
public IEnumerator<IHistoryItem> GetEnumerator() => _items.GetEnumerator();
|
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
|
|
|
public IHistoryItem this[ int index ] => _items[index];
|
|
}
|
|
|
|
internal sealed record SessionProperties(
|
|
MovieTime TimeOffset,
|
|
float PixelsPerSecond,
|
|
int FrameRate );
|
|
|
|
internal sealed record EditModeSnapshot(
|
|
Type Type, EditMode.ISnapshot? Data );
|
|
internal sealed record SessionSnapshot(
|
|
MovieProject.Model Project,
|
|
EditModeSnapshot? EditMode,
|
|
SessionProperties Properties );
|
|
|
|
partial class Session
|
|
{
|
|
public SessionHistory History { get; }
|
|
|
|
internal SessionSnapshot Snapshot() => new (
|
|
Project.Snapshot(),
|
|
EditMode?.Snapshot(),
|
|
new SessionProperties( TimeOffset, PixelsPerSecond, FrameRate ) );
|
|
|
|
internal bool Restore( SessionSnapshot snapshot )
|
|
{
|
|
Project.Restore( snapshot.Project );
|
|
|
|
if ( snapshot.EditMode is { } editMode && SetEditMode( editMode.Type ) && editMode.Data is { } data )
|
|
{
|
|
EditMode?.Restore( data );
|
|
}
|
|
|
|
SetView( snapshot.Properties.TimeOffset, snapshot.Properties.PixelsPerSecond );
|
|
|
|
FrameRate = snapshot.Properties.FrameRate;
|
|
|
|
TrackList.Update();
|
|
|
|
EditMode?.PostRestore();
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
partial class EditMode
|
|
{
|
|
protected internal interface ISnapshot;
|
|
|
|
internal EditModeSnapshot Snapshot() => new( GetType(), OnSnapshot() );
|
|
|
|
protected virtual ISnapshot? OnSnapshot() => null;
|
|
|
|
internal void PreRestore() => OnPreRestore();
|
|
protected virtual void OnPreRestore() { }
|
|
|
|
internal void Restore( ISnapshot snapshot ) => OnRestore( snapshot );
|
|
protected virtual void OnRestore( ISnapshot snapshot ) { }
|
|
|
|
internal void PostRestore() => OnPostRestore();
|
|
protected virtual void OnPostRestore() { }
|
|
}
|