using XFEEDToolBox.Core.Galaxy; namespace XFEEDToolBox.ViewModels; public partial class ToolboxViewModel { private readonly record struct GalaxyAppearanceBinding(int ProcessId,float? ColourBlend,bool? SmallMode); private GalaxyAppearanceBinding? galaxyAppearanceBinding; private void BindGalaxyAppearance(int processId,float? blend,bool? smallMode) { if(processId<=0){ResetGalaxyAppearanceBinding();return;} if(blend is{} value&&(!float.IsFinite(value)||value is <0 or >1))blend=null; var next=new GalaxyAppearanceBinding(processId,blend,smallMode);var previous=galaxyAppearanceBinding; if(previous==next)return; galaxyAppearanceBinding=next; // Small mode selects either immutable raw size in the current selection. // Only the already-mixed colour needs a new native appearance capture. var colourChanged=previous is not{} old||old.ProcessId!=next.ProcessId||old.ColourBlend!=next.ColourBlend; if(colourChanged){galaxyStreaming.Clear();galaxyCellStreaming.Clear();} RefreshCachedGalaxyAppearance(colourChanged,smallMode); } private void ResetGalaxyAppearanceBinding(bool stripCachedMix=true) { galaxyAppearanceBinding=null; if(stripCachedMix)RefreshCachedGalaxyAppearance(true,null); } private static GalacticSystem WithGalaxyAppearanceSmallMode(GalacticSystem system,bool? smallMode) { if(system.OriginalAppearance is not{} original||original.SmallSizeActive==smallMode)return system; return system with{OriginalAppearance=original with{SmallSizeActive=smallMode}}; } private static GalacticSystem StripGalaxyAppearanceMix(GalacticSystem system,bool? smallMode) { if(system.OriginalAppearance is not{} original)return system; if(original.RealisticRgba is null&&original.ColourBlend is null)return WithGalaxyAppearanceSmallMode(system,smallMode); return system with{OriginalAppearance=original with{RealisticRgba=null,ColourBlend=null,SmallSizeActive=smallMode}}; } private void RefreshCachedGalaxyAppearance(bool stripMix,bool? smallMode) { foreach(var name in galaxyCache.Keys.ToArray()) { var previous=galaxyCache[name];var current=stripMix?StripGalaxyAppearanceMix(previous,smallMode):WithGalaxyAppearanceSmallMode(previous,smallMode); if(!ReferenceEquals(previous,current))galaxyCache[name]=current; } } private GalacticSystem ApplyGalaxyAppearanceBinding(GalacticSystem system,int? sourceProcessId,int? currentProcessId,bool recordedProbe) { if(recordedProbe||system.OriginalAppearance is not{} appearance)return system; // A local cached object has already passed this binding. An async native // result otherwise needs its actual originating process supplied by the // caller; merely assigning the current process to an old result is unsafe. if(sourceProcessId is null&&galaxyCache.TryGetValue(system.Name,out var cached)&&ReferenceEquals(cached,system)) sourceProcessId=currentProcessId; var currentSmallMode=galaxyAppearanceBinding is{} current&¤t.ProcessId==currentProcessId?current.SmallMode:null; if(galaxyAppearanceBinding is{} binding&&binding.ProcessId==sourceProcessId&&binding.ProcessId==currentProcessId&& binding.ColourBlend is{} expected&&appearance.ColourBlend==expected)return WithGalaxyAppearanceSmallMode(system,currentSmallMode); return StripGalaxyAppearanceMix(system,currentSmallMode); } }