Code refactor

This commit is contained in:
AbstractConcept 2022-10-27 00:56:04 -05:00
parent cd4711a8e5
commit 757badf4f6
517 changed files with 2534 additions and 2221 deletions

View file

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Events;
namespace RimWorldAnimationStudio
{
public static class EventsManager
{
// Event classes
public class WorkspaceIntEvent : UnityEvent<int> { }
public class ActorEvent : UnityEvent<Actor> { }
public class AnimationStageEvent : UnityEvent<AnimationStage> { }
public class PawnAnimationClipEvent : UnityEvent<PawnAnimationClip> { }
public class PawnKeyframeEvent : UnityEvent<PawnKeyframe> { }
public class ActorAddonEvent : UnityEvent<ActorAddon> { }
public class AddonKeyframeEvent : UnityEvent<AddonKeyframe> { }
// Event list
public static UnityEvent onAnimationDefChanged = new UnityEvent();
public static WorkspaceIntEvent onActorIDChanged = new WorkspaceIntEvent();
public static WorkspaceIntEvent onStageIDChanged = new WorkspaceIntEvent();
public static WorkspaceIntEvent onStageTickChanged = new WorkspaceIntEvent();
public static WorkspaceIntEvent onStageCountChanged = new WorkspaceIntEvent();
public static WorkspaceIntEvent onActorCountChanged = new WorkspaceIntEvent();
public static WorkspaceIntEvent onKeyframeCountChanged = new WorkspaceIntEvent();
public static ActorEvent onActorChanged = new ActorEvent();
public static AnimationStageEvent onAnimationStageChanged = new AnimationStageEvent();
public static PawnAnimationClipEvent onPawnAnimationClipChanged = new PawnAnimationClipEvent();
public static PawnKeyframeEvent onPawnKeyframeChanged = new PawnKeyframeEvent();
public static ActorAddonEvent onActorAddonChanged = new ActorAddonEvent();
public static AddonKeyframeEvent onAddonKeyframeChanged = new AddonKeyframeEvent();
public static UnityEvent onDefNamesChanged = new UnityEvent();
// Event invoking
public static void OnAnimationDefChanged() { onAnimationDefChanged.Invoke(); }
public static void OnActorIDChanged() { onActorIDChanged.Invoke(Workspace.ActorID); }
public static void OnStageIDChanged() { onStageIDChanged.Invoke(Workspace.ActorID); }
public static void OnStageTickChanged() { onStageTickChanged.Invoke(Workspace.StageTick); }
public static void OnStageCountChanged() { onStageCountChanged.Invoke(Workspace.animationDef.AnimationStages.Count); }
public static void OnActorCountChanged() { onActorCountChanged.Invoke(Workspace.animationDef.Actors.Count); }
public static void OnKeyframeCountChanged(PawnAnimationClip clip) { onKeyframeCountChanged.Invoke(clip.Keyframes.Count); }
public static void OnActorChanged(Actor actor) { onActorChanged.Invoke(actor); }
public static void OnAnimationStageChanged(AnimationStage stage) { onAnimationStageChanged.Invoke(stage); }
public static void OnPawnAnimationClipChanged(PawnAnimationClip clip) { onPawnAnimationClipChanged.Invoke(clip); }
public static void OnPawnKeyframeChanged(PawnKeyframe keyframe) { onPawnKeyframeChanged.Invoke(keyframe); }
public static void OnActorAddonChanged(ActorAddon actorAddon) { onActorAddonChanged.Invoke(actorAddon); }
public static void OnAddonKeyframeChanged(AddonKeyframe addonKeyframe) { onAddonKeyframeChanged.Invoke(addonKeyframe); }
public static void OnDefNamesChanged() { onDefNamesChanged.Invoke(); }
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b4b96f2652caaa44985765ae416ac6ea
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -4,28 +4,55 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Events;
namespace RimWorldAnimationStudio
{
public class Workspace : Singleton<Workspace>
public static class Workspace
{
// Animation def
public static AnimationDef animationDef;
public static int stageID = 0;
public static List<int> keyframeID = new List<int>();
[SerializeField] private List<WorkspaceRecord> workspaceHistory = new List<WorkspaceRecord>();
[SerializeField] private int maxHistoryDepth = 100;
// Animation indices set / get
public static int StageID
{
get { return Mathf.Clamp(stageID, 0, animationDef.AnimationStages.Count - 1); }
set
{
bool triggerEvent = stageID != value;
stageID = value;
public static ActorManipulationMode actorManipulationMode = ActorManipulationMode.Pan;
public static ActorBodyPart selectedBodyPart;
if (triggerEvent)
{
StageTick = Constants.minTick;
EventsManager.OnStageIDChanged();
}
}
}
public static List<PawnKeyframe> copiedKeyframes = new List<PawnKeyframe>();
public static int ActorID
{
get { return Mathf.Clamp(actorID, 0, animationDef.Actors.Count - 1); }
set
{
bool triggerEvent = actorID != value;
actorID = value;
public static string animationSavePath;
if (triggerEvent) { EventsManager.OnActorIDChanged(); }
}
}
private static int _actorID = 0;
public static int actorID { get { return Mathf.Clamp(_actorID, 0, animationDef.actors.Count - 1); } set { _actorID = value; } }
public static int StageTick
{
get { return Mathf.Clamp(stageTick, Constants.minTick, StageWindowSize); }
set
{
bool triggerEvent = stageTick != value;
stageTick = value;
if (triggerEvent) { EventsManager.OnStageTickChanged(); }
}
}
public static int StageWindowSize
{
@ -34,58 +61,103 @@ namespace RimWorldAnimationStudio
if (animationDef == null)
{ return -1; }
if (animationDef.animationStages[stageID].stageWindowSize < 0)
{ animationDef.animationStages[stageID].stageWindowSize = animationDef.animationStages[stageID].animationClips.Select(x => x.duration).Max(); }
if (animationDef.AnimationStages[StageID].stageWindowSize < 0)
{ animationDef.AnimationStages[StageID].stageWindowSize = animationDef.AnimationStages[StageID].AnimationClips.Select(x => x.duration).Max(); }
return animationDef.animationStages[stageID].stageWindowSize;
return animationDef.AnimationStages[StageID].stageWindowSize;
}
}
public PawnKeyframe GetCurrentPawnKeyframe(bool makeKeyframe = false)
// Selected keyframes and copied keyframe data
public static List<int> keyframeID = new List<int>();
public static List<PawnKeyframe> copiedKeyframes = new List<PawnKeyframe>();
// Actor manipulation
public static ActorManipulationMode actorManipulationMode = ActorManipulationMode.Pan;
public static ActorBodyPart selectedBodyPart;
// Current save path
public static string animationSavePath;
// Stage loop counts and stretching
public static int stageLoopsNormal = 1;
public static int stageLoopsQuick = 1;
public static bool stretchKeyframes;
// Animation indices
private static int stageID = 0;
private static int actorID = 0;
private static int stageTick = Constants.minTick;
// Workspace history
private static LinkedList<WorkspaceRecord> pastSnapshots = new LinkedList<WorkspaceRecord>();
private static LinkedList<WorkspaceRecord> futureSnapshots = new LinkedList<WorkspaceRecord>();
private static int maxHistoryDepth = 100;
public static Actor GetCurrentActor()
{
int stageTick = AnimationController.Instance.stageTick;
PawnKeyframe keyframe = animationDef?.animationStages[stageID]?.animationClips[actorID]?.keyframes.FirstOrDefault(x => x.atTick == stageTick);
return animationDef?.Actors[ActorID];
}
public static AnimationStage GetCurrentAnimationStage()
{
return animationDef?.AnimationStages[StageID];
}
public static PawnAnimationClip GetCurrentPawnAnimationClip()
{
return animationDef?.AnimationStages[StageID]?.AnimationClips[ActorID];
}
public static PawnKeyframe GetCurrentPawnKeyframe(bool makeKeyframe = false)
{
PawnKeyframe keyframe = animationDef?.AnimationStages[StageID]?.AnimationClips[ActorID]?.Keyframes.FirstOrDefault(x => x.atTick == StageTick);
if (keyframe != null || makeKeyframe == false)
{ return keyframe; }
AnimationController.Instance.AddPawnKeyframe();
return animationDef?.animationStages[stageID]?.animationClips[actorID]?.keyframes.FirstOrDefault(x => x.atTick == stageTick);
GetCurrentPawnAnimationClip().AddPawnKeyframe();
return animationDef?.AnimationStages[StageID]?.AnimationClips[ActorID]?.Keyframes.FirstOrDefault(x => x.atTick == StageTick);
}
public List<PawnKeyframe> GetPawnKeyframesAtTick(int actorID, int atTick)
public static Actor GetActor(int actorID)
{
return animationDef?.animationStages[stageID]?.animationClips[actorID]?.keyframes.Where(x => x.atTick == atTick)?.ToList();
return animationDef?.Actors[actorID];
}
public PawnAnimationClip GetCurrentPawnAnimationClip()
public static AnimationStage GetAnimationStage(int stageID)
{
return animationDef.animationStages[stageID].animationClips[actorID];
return animationDef?.AnimationStages[stageID];
}
public PawnAnimationClip GetPawnAnimationClip(int actorID)
public static PawnAnimationClip GetPawnAnimationClip(int actorID)
{
return animationDef.animationStages[stageID].animationClips[actorID];
return animationDef?.AnimationStages[StageID]?.AnimationClips[actorID];
}
public PawnKeyframe GetPawnKeyframe(int actorID, int keyframeID)
public static PawnKeyframe GetPawnKeyframe(int actorID, int keyframeID)
{
if (stageID < 0) return null;
if (StageID < 0) return null;
if (actorID < 0) return null;
if (stageID >= animationDef.animationStages.Count) return null;
if (actorID >= animationDef.animationStages[stageID].animationClips.Count) return null;
if (StageID >= animationDef.AnimationStages.Count) return null;
if (actorID >= animationDef.AnimationStages[StageID].AnimationClips.Count) return null;
return animationDef.animationStages[stageID].animationClips[actorID].keyframes.FirstOrDefault(x => x.keyframeID == keyframeID);
return animationDef.AnimationStages[StageID].AnimationClips[actorID].Keyframes.FirstOrDefault(x => x.keyframeID == keyframeID);
}
public List<PawnKeyframe> GetPawnKeyframesByID(List<int> keyframeIDs)
public static List<PawnKeyframe> GetAllPawnKeyframesAtTick(int actorID, int atTick)
{
return animationDef?.AnimationStages[StageID]?.AnimationClips[actorID]?.Keyframes.Where(x => x.atTick == atTick)?.ToList();
}
public static List<PawnKeyframe> GetPawnKeyframesByID(List<int> keyframeIDs)
{
List<PawnKeyframe> pawnKeyframes = new List<PawnKeyframe>();
foreach (PawnAnimationClip clip in animationDef.animationStages[stageID].animationClips)
foreach (PawnAnimationClip clip in animationDef.AnimationStages[StageID].AnimationClips)
{
foreach (PawnKeyframe keyframe in clip.keyframes)
foreach (PawnKeyframe keyframe in clip.Keyframes)
{
if (keyframeIDs.Contains(keyframe.keyframeID))
{ pawnKeyframes.Add(keyframe); }
@ -95,15 +167,15 @@ namespace RimWorldAnimationStudio
return pawnKeyframes;
}
public PawnAnimationClip GetAnimationClipThatOwnsKeyframe(int keyframeID, out int clipID)
public static PawnAnimationClip GetAnimationClipThatOwnsKeyframe(int keyframeID, out int clipID)
{
clipID = -1;
for (int i = 0; i < animationDef.animationStages[stageID].animationClips.Count; i++)
for (int i = 0; i < animationDef.AnimationStages[StageID].AnimationClips.Count; i++)
{
PawnAnimationClip clip = animationDef.animationStages[stageID].animationClips[i];
PawnAnimationClip clip = animationDef.AnimationStages[StageID].AnimationClips[i];
if (clip.keyframes.Any(x => x.keyframeID == keyframeID))
if (clip.Keyframes.Any(x => x.keyframeID == keyframeID))
{
clipID = i;
return clip;
@ -113,19 +185,19 @@ namespace RimWorldAnimationStudio
return null;
}
public bool DoesPawnKeyframeExistAtTick(int stageID, int actorID, int atTick)
public static bool DoesPawnKeyframeExistAtTick(int stageID, int actorID, int atTick)
{
return animationDef.animationStages[stageID].animationClips[actorID].keyframes.Any(x => x.atTick == atTick);
return animationDef.AnimationStages[stageID].AnimationClips[actorID].Keyframes.Any(x => x.atTick == atTick);
}
public PawnKeyframe GetNextKeyframe(int actorID)
public static PawnKeyframe GetNextKeyframe(int actorID)
{
PawnKeyframe pawnKeyframe = null;
PawnAnimationClip clip = GetPawnAnimationClip(actorID);
int stageTick = AnimationController.Instance.stageTick;
int stageTick = Workspace.StageTick;
foreach (PawnKeyframe keyframe in clip.keyframes)
foreach (PawnKeyframe keyframe in clip.Keyframes)
{
if (keyframe.atTick > stageTick)
{ pawnKeyframe = keyframe; break; }
@ -134,14 +206,14 @@ namespace RimWorldAnimationStudio
return pawnKeyframe;
}
public PawnKeyframe GetPreviousKeyframe(int actorID)
public static PawnKeyframe GetPreviousKeyframe(int actorID)
{
PawnKeyframe pawnKeyframe = null;
PawnAnimationClip clip = GetPawnAnimationClip(actorID);
int stageTick = AnimationController.Instance.stageTick;
int stageTick = Workspace.StageTick;
foreach (PawnKeyframe keyframe in clip.keyframes)
foreach (PawnKeyframe keyframe in clip.Keyframes)
{
if (keyframe.atTick < stageTick)
{ pawnKeyframe = keyframe; }
@ -150,14 +222,14 @@ namespace RimWorldAnimationStudio
return pawnKeyframe;
}
public PawnKeyframe GetCurrentOrPreviousKeyframe(int actorID)
public static PawnKeyframe GetCurrentOrPreviousKeyframe(int actorID)
{
PawnKeyframe pawnKeyframe = null;
PawnAnimationClip clip = GetPawnAnimationClip(actorID);
int stageTick = AnimationController.Instance.stageTick;
int stageTick = Workspace.StageTick;
foreach (PawnKeyframe keyframe in clip.keyframes)
foreach (PawnKeyframe keyframe in clip.Keyframes)
{
if (keyframe.atTick <= stageTick)
{ pawnKeyframe = keyframe; }
@ -172,12 +244,12 @@ namespace RimWorldAnimationStudio
if (excludedActorID >= 0)
{
keyframesToCheck = animationDef.animationStages[stageID].animationClips.Where(x =>
animationDef.animationStages[stageID].animationClips.IndexOf(x) != excludedActorID).SelectMany(x => x.keyframes)?.ToList();
keyframesToCheck = animationDef.AnimationStages[StageID].AnimationClips.Where(x =>
animationDef.AnimationStages[StageID].AnimationClips.IndexOf(x) != excludedActorID).SelectMany(x => x.Keyframes)?.ToList();
}
else
{ keyframesToCheck = animationDef.animationStages[stageID].animationClips.SelectMany(x => x.keyframes)?.ToList(); }
{ keyframesToCheck = animationDef.AnimationStages[StageID].AnimationClips.SelectMany(x => x.Keyframes)?.ToList(); }
keyframesToCheck = keyframesToCheck.Where(x => Mathf.Abs(atTick - x.atTick.Value) <= searchDistance)?.ToList();
@ -199,36 +271,32 @@ namespace RimWorldAnimationStudio
return bestAtTick;
}
public int GetEarliestAtTickInCopiedKeyframes(int actorID)
public static int GetEarliestAtTickInCopiedKeyframes(int actorID)
{
IEnumerable<Keyframe> keyframes = copiedKeyframes.Where(x => x.actorID == actorID);
IEnumerable<PawnKeyframe> keyframes = copiedKeyframes.Where(x => x.actorID == actorID);
if (keyframes == null || keyframes.Any() == false) return -1;
return keyframes.Min(x => x.atTick).Value;
}
[SerializeField]
public LinkedList<WorkspaceRecord> pastSnapshots = new LinkedList<WorkspaceRecord>();
public LinkedList<WorkspaceRecord> futureSnapshots = new LinkedList<WorkspaceRecord>();
public void Reset()
public static void Reset()
{
actorID = 0;
stageID = 0;
ActorID = 0;
StageID = 0;
keyframeID.Clear();
selectedBodyPart = null;
animationSavePath = null;
ClearHistory();
}
public void MakeHistoricRecord(string eventDesc)
public static void MakeHistoricRecord(string eventDesc)
{
WorkspaceRecord record = new WorkspaceRecord();
record.recordID = pastSnapshots.Count;
record.eventDesc = eventDesc;
record.animationDef = animationDef.Copy();
record.stageID = stageID;
record.stageID = StageID;
futureSnapshots.Clear();
pastSnapshots.AddLast(record);
@ -237,16 +305,16 @@ namespace RimWorldAnimationStudio
{ pastSnapshots.RemoveFirst(); }
}
public void RestoreToHistoricRecord(WorkspaceRecord record)
public static void RestoreToHistoricRecord(WorkspaceRecord record)
{
animationDef = record.animationDef.Copy();
stageID = record.stageID;
StageID = record.stageID;
AnimationController.Instance.MakeTimelineDirty();
StageCardManager.Instance.Initialize();
}
public void Undo()
public static void Undo()
{
WorkspaceRecord recordToRead = pastSnapshots.Last?.Previous?.Value;
WorkspaceRecord recordToStore = pastSnapshots.Last?.Value;
@ -258,9 +326,11 @@ namespace RimWorldAnimationStudio
RestoreToHistoricRecord(recordToRead);
Debug.Log("Undoing : " + recordToStore.eventDesc);
EventsManager.OnAnimationDefChanged();
}
public void Redo()
public static void Redo()
{
WorkspaceRecord recordToReadAndStore = futureSnapshots.Last?.Value;
@ -271,15 +341,17 @@ namespace RimWorldAnimationStudio
RestoreToHistoricRecord(recordToReadAndStore);
Debug.Log("Redoing : " + recordToReadAndStore.eventDesc);
EventsManager.OnAnimationDefChanged();
}
public void ClearHistory()
public static void ClearHistory()
{
pastSnapshots.Clear();
futureSnapshots.Clear();
}
public void RecordEvent(string eventDesc)
public static void RecordEvent(string eventDesc)
{
//Debug.Log("Recording event: " + eventDesc + " (record ID: " + pastSnapshots.Count + ")");
MakeHistoricRecord(eventDesc);