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);
}
}
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);
}
}