Clean separation between track data and config overrides
In debug builds Config keeps a reference to the last set original track instance from which it can load original values.
This commit is contained in:
		
							parent
							
								
									525c0e108f
								
							
						
					
					
						commit
						d4d3e15de3
					
				|  | @ -917,7 +917,32 @@ namespace MuzikaGromche | |||
| 
 | ||||
|         public Palette Palette { get; } | ||||
|     } | ||||
|   | ||||
| 
 | ||||
|     // A proxy audio track with default implementation for every IAudioTrack method that simply forwards requests to the inner IAudioTrack. | ||||
|     public abstract class ProxyAudioTrack(IAudioTrack track) : IAudioTrack | ||||
|     { | ||||
|         internal IAudioTrack Track = track; | ||||
|         string IAudioTrack.Name => Track.Name; | ||||
|         float IAudioTrack.WindUpTimer => Track.WindUpTimer; | ||||
|         int IAudioTrack.Beats => Track.Beats; | ||||
|         int IAudioTrack.LoopOffset => Track.LoopOffset; | ||||
|         AudioType IAudioTrack.AudioType => Track.AudioType; | ||||
|         AudioClip IAudioTrack.LoadedIntro { get => Track.LoadedIntro; set => Track.LoadedIntro = value; } | ||||
|         AudioClip IAudioTrack.LoadedLoop { get => Track.LoadedLoop; set => Track.LoadedLoop = value; } | ||||
|         string IAudioTrack.FileNameIntro => Track.FileNameIntro; | ||||
|         string IAudioTrack.FileNameLoop => Track.FileNameLoop; | ||||
|         float IAudioTrack.BeatsOffset => Track.BeatsOffset; | ||||
|         float IAudioTrack.FadeOutBeat => Track.FadeOutBeat; | ||||
|         float IAudioTrack.FadeOutDuration => Track.FadeOutDuration; | ||||
|         float IAudioTrack.ColorTransitionIn => Track.ColorTransitionIn; | ||||
|         float IAudioTrack.ColorTransitionOut => Track.ColorTransitionOut; | ||||
|         Easing IAudioTrack.ColorTransitionEasing => Track.ColorTransitionEasing; | ||||
|         float[] IAudioTrack.FlickerLightsTimeSeries => Track.FlickerLightsTimeSeries; | ||||
|         float[] IAudioTrack.LyricsTimeSeries => Track.LyricsTimeSeries; | ||||
|         string[] IAudioTrack.LyricsLines => Track.LyricsLines; | ||||
|         Palette IAudioTrack.Palette => Track.Palette; | ||||
|     } | ||||
| 
 | ||||
|     // Core audio track implementation with some defaults and config overrides. | ||||
|     // Suitable to declare elemnents of SelectableTracksGroup and as a base for standalone selectable tracks. | ||||
|     public class CoreAudioTrack : IAudioTrack | ||||
|  | @ -951,56 +976,17 @@ namespace MuzikaGromche | |||
|             init => FileNameLoopOverride = value; | ||||
|         } | ||||
| 
 | ||||
|         public float _BeatsOffset = 0f; | ||||
|         public float BeatsOffset | ||||
|         { | ||||
|             get => Config.BeatsOffsetOverride ?? _BeatsOffset; | ||||
|             init => _BeatsOffset = value; | ||||
|         } | ||||
| 
 | ||||
|         public float _FadeOutBeat = float.NaN; | ||||
|         public float FadeOutBeat | ||||
|         { | ||||
|             get => Config.FadeOutBeatOverride ?? _FadeOutBeat; | ||||
|             init => _FadeOutBeat = value; | ||||
|         } | ||||
| 
 | ||||
|         public float _FadeOutDuration = 2f; | ||||
|         public float FadeOutDuration | ||||
|         { | ||||
|             get => Config.FadeOutDurationOverride ?? _FadeOutDuration; | ||||
|             init => _FadeOutDuration = value; | ||||
|         } | ||||
| 
 | ||||
|         // Duration of color transition, measured in beats. | ||||
|         public float _ColorTransitionIn = 0.25f; | ||||
|         public float ColorTransitionIn | ||||
|         { | ||||
|             get => Config.ColorTransitionInOverride ?? _ColorTransitionIn; | ||||
|             init => _ColorTransitionIn = value; | ||||
|         } | ||||
| 
 | ||||
|         public float _ColorTransitionOut = 0.25f; | ||||
|         public float ColorTransitionOut | ||||
|         { | ||||
|             get => Config.ColorTransitionOutOverride ?? _ColorTransitionOut; | ||||
|             init => _ColorTransitionOut = value; | ||||
|         } | ||||
| 
 | ||||
|         // Easing function for color transitions. | ||||
|         public Easing _ColorTransitionEasing = Easing.OutExpo; | ||||
|         public Easing ColorTransitionEasing | ||||
|         { | ||||
|             get => Config.ColorTransitionEasingOverride != null | ||||
|                 ? Easing.FindByName(Config.ColorTransitionEasingOverride) | ||||
|                 : _ColorTransitionEasing; | ||||
|             init => _ColorTransitionEasing = value; | ||||
|         } | ||||
|         public float BeatsOffset { get; init; } = 0f; | ||||
|         public float FadeOutBeat { get; init; } = float.NaN; | ||||
|         public float FadeOutDuration { get; init; } = 2f; | ||||
|         public float ColorTransitionIn { get; init; } = 0.25f; | ||||
|         public float ColorTransitionOut { get; init; } = 0.25f; | ||||
|         public Easing ColorTransitionEasing { get; init; } = Easing.OutExpo; | ||||
| 
 | ||||
|         public float[] _FlickerLightsTimeSeries = []; | ||||
|         public float[] FlickerLightsTimeSeries | ||||
|         { | ||||
|             get => Config.FlickerLightsTimeSeriesOverride ?? _FlickerLightsTimeSeries; | ||||
|             get => _FlickerLightsTimeSeries; | ||||
|             init | ||||
|             { | ||||
|                 Array.Sort(value); | ||||
|  | @ -1008,12 +994,7 @@ namespace MuzikaGromche | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public float[] _LyricsTimeSeries = []; | ||||
|         public float[] LyricsTimeSeries | ||||
|         { | ||||
|             get => Config.LyricsTimeSeriesOverride ?? _LyricsTimeSeries; | ||||
|             private set => _LyricsTimeSeries = value; | ||||
|         } | ||||
|         public float[] LyricsTimeSeries { get; private set; } = []; | ||||
| 
 | ||||
|         // Lyrics line may contain multiple tab-separated alternatives. | ||||
|         // In such case, a random number chosen and updated once per loop | ||||
|  | @ -1034,12 +1015,7 @@ namespace MuzikaGromche | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public Palette _Palette = Palette.DEFAULT; | ||||
|         public Palette Palette | ||||
|         { | ||||
|             get => Config.PaletteOverride ?? _Palette; | ||||
|             set => _Palette = value; | ||||
|         } | ||||
|         public Palette Palette { get; set; } = Palette.DEFAULT; | ||||
|     } | ||||
| 
 | ||||
|     // Standalone, top-level, selectable audio track | ||||
|  | @ -1853,9 +1829,6 @@ namespace MuzikaGromche | |||
|         : SyncedConfig2<Config> | ||||
| #endif | ||||
|     { | ||||
|         // Latest set track, used for loading palette and timings. | ||||
|         public static IAudioTrack? CurrentTrack { get; internal set; } = null; | ||||
| 
 | ||||
|         public static ConfigEntry<bool> DisplayLyrics { get; private set; } = null!; | ||||
| 
 | ||||
|         public static ConfigEntry<float> AudioOffset { get; private set; } = null!; | ||||
|  | @ -1867,16 +1840,45 @@ namespace MuzikaGromche | |||
|         public static bool ExtrapolateTime { get; private set; } = true; | ||||
|         public static bool ShouldSkipWindingPhase { get; private set; } = false; | ||||
| 
 | ||||
|         public static Palette? PaletteOverride { get; private set; } = null; | ||||
| #if DEBUG | ||||
|         // Latest set track, used for loading palette and timings. | ||||
|         private static IAudioTrack? CurrentTrack = null; | ||||
|         // All per-track values that can be overridden | ||||
|         private static float? BeatsOffsetOverride = null; | ||||
|         private static float? FadeOutBeatOverride = null; | ||||
|         private static float? FadeOutDurationOverride = null; | ||||
|         private static float? ColorTransitionInOverride = null; | ||||
|         private static float? ColorTransitionOutOverride = null; | ||||
|         private static string? ColorTransitionEasingOverride = null; | ||||
|         private static float[]? FlickerLightsTimeSeriesOverride = null; | ||||
|         private static float[]? LyricsTimeSeriesOverride = null; | ||||
|         private static Palette? PaletteOverride = null; | ||||
| 
 | ||||
|         public static float? FadeOutBeatOverride { get; private set; } = null; | ||||
|         public static float? FadeOutDurationOverride { get; private set; } = null; | ||||
|         public static float[]? FlickerLightsTimeSeriesOverride { get; private set; } = null; | ||||
|         public static float[]? LyricsTimeSeriesOverride { get; private set; } = null; | ||||
|         public static float? BeatsOffsetOverride { get; private set; } = null; | ||||
|         public static float? ColorTransitionInOverride { get; private set; } = null; | ||||
|         public static float? ColorTransitionOutOverride { get; private set; } = null; | ||||
|         public static string? ColorTransitionEasingOverride { get; private set; } = null; | ||||
|         private class AudioTrackWithConfigOverride(IAudioTrack track) : ProxyAudioTrack(track), IAudioTrack | ||||
|         { | ||||
|             float IAudioTrack.BeatsOffset => BeatsOffsetOverride ?? Track.BeatsOffset; | ||||
| 
 | ||||
|             float IAudioTrack.FadeOutBeat => FadeOutBeatOverride ?? Track.FadeOutBeat; | ||||
| 
 | ||||
|             float IAudioTrack.FadeOutDuration => FadeOutDurationOverride ?? Track.FadeOutDuration; | ||||
| 
 | ||||
|             float IAudioTrack.ColorTransitionIn => ColorTransitionInOverride ?? Track.ColorTransitionIn; | ||||
| 
 | ||||
|             float IAudioTrack.ColorTransitionOut => ColorTransitionOutOverride ?? Track.ColorTransitionOut; | ||||
| 
 | ||||
|             Easing IAudioTrack.ColorTransitionEasing => | ||||
|                 ColorTransitionEasingOverride != null | ||||
|                     ? Easing.FindByName(ColorTransitionEasingOverride) | ||||
|                     : Track.ColorTransitionEasing; | ||||
| 
 | ||||
|             float[] IAudioTrack.FlickerLightsTimeSeries => | ||||
|                 FlickerLightsTimeSeriesOverride ?? Track.FlickerLightsTimeSeries; | ||||
| 
 | ||||
|             float[] IAudioTrack.LyricsTimeSeries => LyricsTimeSeriesOverride ?? Track.LyricsTimeSeries; | ||||
| 
 | ||||
|             Palette IAudioTrack.Palette => PaletteOverride ?? Track.Palette; | ||||
|         } | ||||
| #endif | ||||
| 
 | ||||
|         internal Config(ConfigFile configFile) | ||||
| #if DEBUG | ||||
|  | @ -1955,6 +1957,16 @@ namespace MuzikaGromche | |||
| #endif | ||||
|         } | ||||
| 
 | ||||
|         internal static IAudioTrack OverrideCurrentTrack(IAudioTrack track) | ||||
|         { | ||||
| #if DEBUG | ||||
|             CurrentTrack = track; | ||||
|             return new AudioTrackWithConfigOverride(track); | ||||
| #else | ||||
|             return track; | ||||
| #endif | ||||
|         } | ||||
| 
 | ||||
| #if DEBUG | ||||
|         // HACK because CSync doesn't provide an API to register a list of config entries | ||||
|         // See https://github.com/lc-sigurd/CSync/issues/11 | ||||
|  | @ -2068,7 +2080,7 @@ namespace MuzikaGromche | |||
| 
 | ||||
|             void load() | ||||
|             { | ||||
|                 var palette = (CurrentTrack as CoreAudioTrack)?._Palette ?? Palette.DEFAULT; | ||||
|                 var palette = CurrentTrack?.Palette ?? Palette.DEFAULT; | ||||
|                 var colors = palette.Colors; | ||||
|                 var count = Math.Min(colors.Count(), maxCustomPaletteSize); | ||||
| 
 | ||||
|  | @ -2101,7 +2113,7 @@ namespace MuzikaGromche | |||
|             const string section = "Timings"; | ||||
|             var colorTransitionRange = new AcceptableValueRange<float>(0f, 1f); | ||||
|             // Declare and initialize early to avoid "Use of unassigned local variable" | ||||
|             List<(Action<CoreAudioTrack?> Load, Action Apply)> entries = []; | ||||
|             List<(Action<IAudioTrack?> Load, Action Apply)> entries = []; | ||||
|             SyncedEntry<bool> overrideTimingsSyncedEntry = null!; | ||||
|             SyncedEntry<float> fadeOutBeatSyncedEntry = null!; | ||||
|             SyncedEntry<float> fadeOutDurationSyncedEntry = null!; | ||||
|  | @ -2151,21 +2163,21 @@ namespace MuzikaGromche | |||
|             LethalConfigManager.AddConfigItem(new FloatSliderConfigItem(colorTransitionOutSyncedEntry.Entry, floatSliderOptions)); | ||||
|             LethalConfigManager.AddConfigItem(new TextDropDownConfigItem(colorTransitionEasingSyncedEntry.Entry, Default(new TextDropDownOptions()))); | ||||
| 
 | ||||
|             registerStruct(fadeOutBeatSyncedEntry, t => t._FadeOutBeat, x => FadeOutBeatOverride = x); | ||||
|             registerStruct(fadeOutDurationSyncedEntry, t => t._FadeOutDuration, x => FadeOutDurationOverride = x); | ||||
|             registerArray(flickerLightsTimeSeriesSyncedEntry, t => t._FlickerLightsTimeSeries, xs => FlickerLightsTimeSeriesOverride = xs, float.Parse, sort: true); | ||||
|             registerArray(lyricsTimeSeriesSyncedEntry, t => t._LyricsTimeSeries, xs => LyricsTimeSeriesOverride = xs, float.Parse, sort: true); | ||||
|             registerStruct(beatsOffsetSyncedEntry, t => t._BeatsOffset, x => BeatsOffsetOverride = x); | ||||
|             registerStruct(colorTransitionInSyncedEntry, t => t._ColorTransitionIn, x => ColorTransitionInOverride = x); | ||||
|             registerStruct(colorTransitionOutSyncedEntry, t => t._ColorTransitionOut, x => ColorTransitionOutOverride = x); | ||||
|             registerClass(colorTransitionEasingSyncedEntry, t => t._ColorTransitionEasing.Name, x => ColorTransitionEasingOverride = x); | ||||
|             registerStruct(fadeOutBeatSyncedEntry, t => t.FadeOutBeat, x => FadeOutBeatOverride = x); | ||||
|             registerStruct(fadeOutDurationSyncedEntry, t => t.FadeOutDuration, x => FadeOutDurationOverride = x); | ||||
|             registerArray(flickerLightsTimeSeriesSyncedEntry, t => t.FlickerLightsTimeSeries, xs => FlickerLightsTimeSeriesOverride = xs, float.Parse, sort: true); | ||||
|             registerArray(lyricsTimeSeriesSyncedEntry, t => t.LyricsTimeSeries, xs => LyricsTimeSeriesOverride = xs, float.Parse, sort: true); | ||||
|             registerStruct(beatsOffsetSyncedEntry, t => t.BeatsOffset, x => BeatsOffsetOverride = x); | ||||
|             registerStruct(colorTransitionInSyncedEntry, t => t.ColorTransitionIn, x => ColorTransitionInOverride = x); | ||||
|             registerStruct(colorTransitionOutSyncedEntry, t => t.ColorTransitionOut, x => ColorTransitionOutOverride = x); | ||||
|             registerClass(colorTransitionEasingSyncedEntry, t => t.ColorTransitionEasing.Name, x => ColorTransitionEasingOverride = x); | ||||
| 
 | ||||
|             void register<T>(SyncedEntry<T> syncedEntry, Func<CoreAudioTrack, T> getter, Action applier) | ||||
|             void register<T>(SyncedEntry<T> syncedEntry, Func<IAudioTrack, T> getter, Action applier) | ||||
|             { | ||||
|                 CSyncHackAddSyncedEntry(syncedEntry); | ||||
|                 syncedEntry.SyncHostToLocal(); | ||||
|                 syncedEntry.Changed += (sender, args) => applier(); | ||||
|                 void loader(CoreAudioTrack? track) | ||||
|                 void loader(IAudioTrack? track) | ||||
|                 { | ||||
|                     // if track is null, set everything to defaults | ||||
|                     syncedEntry.LocalValue = track == null ? (T)syncedEntry.Entry.DefaultValue : getter(track); | ||||
|  | @ -2173,11 +2185,11 @@ namespace MuzikaGromche | |||
|                 entries.Add((loader, applier)); | ||||
|             } | ||||
| 
 | ||||
|             void registerStruct<T>(SyncedEntry<T> syncedEntry, Func<CoreAudioTrack, T> getter, Action<T?> setter) where T : struct => | ||||
|             void registerStruct<T>(SyncedEntry<T> syncedEntry, Func<IAudioTrack, T> getter, Action<T?> setter) where T : struct => | ||||
|                 register(syncedEntry, getter, () => setter.Invoke(overrideTimingsSyncedEntry.Value ? syncedEntry.Value : null)); | ||||
|             void registerClass<T>(SyncedEntry<T> syncedEntry, Func<CoreAudioTrack, T> getter, Action<T?> setter) where T : class => | ||||
|             void registerClass<T>(SyncedEntry<T> syncedEntry, Func<IAudioTrack, T> getter, Action<T?> setter) where T : class => | ||||
|                 register(syncedEntry, getter, () => setter.Invoke(overrideTimingsSyncedEntry.Value ? syncedEntry.Value : null)); | ||||
|             void registerArray<T>(SyncedEntry<string> syncedEntry, Func<CoreAudioTrack, T[]> getter, Action<T[]?> setter, Func<string, T> parser, bool sort = false) where T : struct => | ||||
|             void registerArray<T>(SyncedEntry<string> syncedEntry, Func<IAudioTrack, T[]> getter, Action<T[]?> setter, Func<string, T> parser, bool sort = false) where T : struct => | ||||
|                 register(syncedEntry, | ||||
|                     (track) => string.Join(", ", getter(track)), | ||||
|                     () => | ||||
|  | @ -2208,10 +2220,9 @@ namespace MuzikaGromche | |||
| 
 | ||||
|             void load() | ||||
|             { | ||||
|                 var track = CurrentTrack; | ||||
|                 foreach (var entry in entries) | ||||
|                 { | ||||
|                     entry.Load(track as CoreAudioTrack); | ||||
|                     entry.Load(CurrentTrack); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|  | @ -2354,7 +2365,10 @@ namespace MuzikaGromche | |||
|         public void SetTrackClientRpc(string name) | ||||
|         { | ||||
|             Debug.Log($"{nameof(MuzikaGromche)} SetTrackClientRpc {name}"); | ||||
|             Config.CurrentTrack = CurrentTrack = Plugin.FindTrackNamed(name); | ||||
|             if (Plugin.FindTrackNamed(name) is { } track) | ||||
|             { | ||||
|                 CurrentTrack = Config.OverrideCurrentTrack(track); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         [ServerRpc] | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue