Skip to content

Commit

Permalink
Initial work on the undo/redo system
Browse files Browse the repository at this point in the history
  • Loading branch information
skyloutyr committed Feb 20, 2024
1 parent f10399c commit 4395dee
Show file tree
Hide file tree
Showing 12 changed files with 396 additions and 5 deletions.
4 changes: 3 additions & 1 deletion VTT/Control/TurnTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public TurnTracker(Map container)
}

public void Sort() => this.Entries.Sort((l, r) => r.NumericValue.CompareTo(l.NumericValue));
public void Add(Entry e, int idx)
public int Add(Entry e, int idx)
{
if (idx <= this.EntryIndex)
{
Expand All @@ -38,10 +38,12 @@ public void Add(Entry e, int idx)
if (idx >= this.Entries.Count)
{
this.Entries.Add(e);
return this.Entries.Count - 1;
}
else
{
this.Entries.Insert(idx, e);
return idx;
}
}

Expand Down
2 changes: 2 additions & 0 deletions VTT/Network/Packet/PacketAddOrUpdateDrawing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System;
using System.IO;
using VTT.Control;
using VTT.Network.UndoRedo;
using VTT.Util;

public class PacketAddOrUpdateDrawing : PacketBase
Expand Down Expand Up @@ -52,6 +53,7 @@ public override void Act(Guid sessionID, Server server, Client client, bool isSe
m.Drawings.Add(this.DPC);
}

this.Sender.ActionMemory.NewAction(new DrawingAction() { Container = m, DPC = this.DPC, LastModifyTime = DateTime.Now });
m.NeedsSave = true;
this.Broadcast(c => c.ClientMapID.Equals(this.MapID));
}
Expand Down
6 changes: 4 additions & 2 deletions VTT/Network/Packet/PacketAddTurnEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System;
using System.IO;
using VTT.Control;
using VTT.Network.UndoRedo;
using VTT.Util;

public class PacketAddTurnEntry : PacketBase
Expand All @@ -13,7 +14,6 @@ public class PacketAddTurnEntry : PacketBase
public int AdditionIndex { get; set; }
public override uint PacketID => 2;


public override void Act(Guid sessionID, Server server, Client client, bool isServer)
{
Logger l = this.GetContextLogger();
Expand All @@ -33,14 +33,16 @@ public override void Act(Guid sessionID, Server server, Client client, bool isSe

TurnTracker.Team t = m.TurnTracker.Teams.Find(p => p.Name.Equals(this.TeamName)) ?? m.TurnTracker.Teams[0];
TurnTracker.Entry e = new TurnTracker.Entry() { NumericValue = this.Value, ObjectID = this.ObjectID, Team = t };
int ei;
lock (m.TurnTracker.Lock)
{
m.TurnTracker.Add(e, this.AdditionIndex == -1 ? m.TurnTracker.Entries.Count : this.AdditionIndex);
ei = m.TurnTracker.Add(e, this.AdditionIndex == -1 ? m.TurnTracker.Entries.Count : this.AdditionIndex);
}

if (isServer)
{
m.NeedsSave = true;
this.Sender.ActionMemory.NewAction(new AddTurnEntryAction() { EntryIndex = ei, AdditionIndex = this.AdditionIndex, EntryObjectID = this.ObjectID, Map = m, NumericValue = this.Value, TeamName = this.TeamName });
this.Broadcast(c => c.ClientMapID.Equals(m.ID));
}
}
Expand Down
1 change: 1 addition & 0 deletions VTT/Network/Packet/PacketAnimationRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public override void Act(Guid sessionID, Server server, Client client, bool isSe
}
}

// TODO animation request undo/redo memory!
m.NeedsSave = true;
this.Broadcast(x => x.ClientMapID.Equals(this.MapID));
}
Expand Down
29 changes: 27 additions & 2 deletions VTT/Network/Packet/PacketAura.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
using System;
using System.IO;
using VTT.Control;
using VTT.Network.UndoRedo;
using VTT.Util;

public class PacketAura : PacketBase
{
public Guid MapID { get; set; }
public Guid ObjectID { get; set; }
public int Index { get; set; }
public int Index { get; set; } = -1;
public Color AuraColor { get; set; }
public float AuraRange { get; set; }
public Action ActionType { get; set; }
Expand Down Expand Up @@ -63,25 +64,49 @@ public override void Act(Guid sessionID, Server server, Client client, bool isSe
{
lock (mo.Lock)
{
mo.Auras.Add((this.AuraRange, this.AuraColor));
if (this.Index == -1)
{
mo.Auras.Add((this.AuraRange, this.AuraColor));
}
else
{
mo.Auras.Insert(this.Index, (this.AuraRange, this.AuraColor));
}
}

if (isServer)
{
this.Sender.ActionMemory.NewAction(new AuraAddOrDeleteAction() { IsAddition = true, AuraColor = this.AuraColor, AuraContainer = mo, AuraIndex = mo.Auras.Count - 1, AuraRange = this.AuraRange });
}

break;
}

case Action.Delete:
{
(float, Color) data = mo.Auras[this.Index];
lock (mo.Lock)
{
mo.Auras.RemoveAt(this.Index);
}

if (isServer)
{
this.Sender.ActionMemory.NewAction(new AuraAddOrDeleteAction() { IsAddition = false, AuraColor = data.Item2, AuraContainer = mo, AuraIndex = this.Index, AuraRange = data.Item1 });
}

break;
}

case Action.Update:
{
(float, Color) data = mo.Auras[this.Index];
mo.Auras[this.Index] = (this.AuraRange, this.AuraColor);
if (isServer)
{
this.Sender.ActionMemory.NewAction(new AuraChangeAction() { AuraContainer = mo, AuraIndex = this.Index, InitialAuraColor = data.Item2, InitialAuraRange = data.Item1, LastModifyTime = DateTime.Now, NewAuraColor = this.AuraColor, NewAuraRange = this.AuraRange });
}

break;
}
}
Expand Down
5 changes: 5 additions & 0 deletions VTT/Network/Packet/PacketHandshake.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ public override void Act(Guid sessionID, Server server, Client client, bool isSe
}

server.ClientInfos[ci.ID] = ci;
if (sc.IsAdmin)
{
sc.ActionMemory.ActionBufferSize = 128;
}

PacketClientInfo pci = new PacketClientInfo() { IsAdmin = sc.IsAdmin, IsObserver = sc.IsObserver, Session = sessionID, IsServer = isServer };
pci.Send(sc);
new PacketClientData() { InfosToUpdate = server.ClientInfos.Values.ToList() }.Send(sc);
Expand Down
3 changes: 3 additions & 0 deletions VTT/Network/Server.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using VTT.Asset;
using VTT.Control;
using VTT.Network.Packet;
using VTT.Network.UndoRedo;
using VTT.Util;

public class Server : TcpServer
Expand Down Expand Up @@ -769,6 +770,7 @@ public class ServerClient : TcpSession
{
public ClientInfo Info { get; set; }
public long LastPingResponseTime { get; set; }
public ActionMemory ActionMemory { get; set; }

public Guid ID
{
Expand Down Expand Up @@ -819,6 +821,7 @@ public ServerClient(TcpServer server) : base(server)
{
this.Container = (Server)server;
this.LocalNetManager = new PacketNetworkManager() { IsServer = true };
this.ActionMemory = new ActionMemory(this);
}

public void SetClientInfo(ClientInfo info)
Expand Down
116 changes: 116 additions & 0 deletions VTT/Network/UndoRedo/ActionMemory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
namespace VTT.Network.UndoRedo
{
using System;
using System.Collections.Generic;
using VTT.Control;
using VTT.Network.Packet;

public class ActionMemory
{
private readonly List<ServerAction> _actions = new List<ServerAction>();
private readonly object _lock = new object();
private ServerClient _owner;

public ActionMemory(ServerClient serverClient) => this._owner = serverClient;

public Guid Owner { get; set; }
public int ActionAmount => _actions.Count;
public int CurrentIndex { get; set; } = -1;
public int ActionBufferSize { get; set; } = 32;

public void NewAction(ServerAction sa)
{
if (sa is SmallChangeAction sca && _actions.Count > 0)
{
lock (_lock)
{
ServerAction csa = _actions[CurrentIndex];
if (csa is SmallChangeAction sccsa && sccsa.ActionType == sa.ActionType)
{
if (sccsa.AcceptSmallChange(sca))
{
return;
}
}
}
}

lock (_lock)
{
if (CurrentIndex < _actions.Count - 1)
{
_actions.RemoveRange(CurrentIndex + 1, _actions.Count - CurrentIndex - 1);
}

if (this._actions.Count + 1 > this.ActionBufferSize)
{
this._actions.RemoveAt(0);
--this.CurrentIndex;
}

_actions.Add(sa);
++CurrentIndex;
}
}

public bool UndoAction()
{
lock (_lock)
{
if (_actions.Count > 0 && CurrentIndex >= 0)
{
ServerAction sa = _actions[CurrentIndex];
sa.Undo();
--CurrentIndex;
return true;
}

return false;
}
}

public bool RedoAction()
{
lock (_lock)
{
if (_actions.Count < CurrentIndex + 1)
{
ServerAction sa = _actions[CurrentIndex + 1];
sa.Redo();
++CurrentIndex;
return true;
}

return false;
}
}
}

public abstract class ServerAction
{
public abstract ServerActionType ActionType { get; }

public abstract void Undo();
public abstract void Redo();

public void SendToAllOnMap(Map cMap, PacketBase packet) => packet.Broadcast(x => x.ClientMapID.Equals(cMap.ID));
}

public abstract class SmallChangeAction : ServerAction
{
public DateTime LastModifyTime { get; set; }

public abstract bool AcceptSmallChange(SmallChangeAction newAction);

public bool CheckIfRecent(DateTime otherTime, int ms) => (otherTime - this.LastModifyTime).Milliseconds <= ms;
}

public enum ServerActionType
{
Unknown,
AddDrawing,
AddTurnEntry,
AuraAddOrRemove,
AuraChange
}
}
58 changes: 58 additions & 0 deletions VTT/Network/UndoRedo/AddTurnEntryAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
namespace VTT.Network.UndoRedo
{
using System;
using VTT.Control;
using VTT.Network.Packet;

public class AddTurnEntryAction : ServerAction
{
public override ServerActionType ActionType => ServerActionType.AddTurnEntry;
public Guid EntryObjectID { get; set; }
public int AdditionIndex { get; set; }
public float NumericValue { get; set; }
public string TeamName { get; set; }
public int EntryIndex { get; set; }
public Map Map { get; set; }

public int SafeGetEntryAtIndex()
{
lock (this.Map.TurnTracker.Lock)
{
if (this.EntryIndex < 0 || this.EntryIndex >= this.Map.TurnTracker.Entries.Count)
{
return -1;
}

return this.EntryIndex;
}
}

public override void Redo()
{
int e = this.SafeGetEntryAtIndex();
if (e == -1)
{
TurnTracker.Team t = (string.IsNullOrEmpty(this.TeamName) ? this.Map.TurnTracker.Teams[0] : this.Map.TurnTracker.Teams.Find(x => x.Name.Equals(this.TeamName))) ?? this.Map.TurnTracker.Teams[0];
lock (this.Map.TurnTracker.Lock)
{
this.Map.TurnTracker.Add(new TurnTracker.Entry() { NumericValue = this.NumericValue, ObjectID = this.EntryObjectID, Team = t }, this.AdditionIndex == -1 ? this.Map.TurnTracker.Entries.Count : this.AdditionIndex);
}

this.Map.NeedsSave = true;
new PacketAddTurnEntry() { AdditionIndex = this.AdditionIndex, ObjectID = this.EntryObjectID, TeamName = this.TeamName, Value = this.NumericValue }.Broadcast(x => x.ClientMapID.Equals(this.Map.ID));
}
}

public override void Undo()
{
int e = this.SafeGetEntryAtIndex();
if (e != -1)
{
lock (this.Map.TurnTracker.Lock)
{
this.Map.TurnTracker.Remove(e);
}
}
}
}
}
Loading

0 comments on commit 4395dee

Please sign in to comment.