Files
Enigmos/Boards/BaseBoard.cs
2024-07-13 09:29:45 +01:00

221 lines
7.5 KiB
C#

using Alchegos.DataStructure;
using Enigmos.Cables;
using Enigmos.Modules;
using Enigmos.Modules.ProgrammableModules;
using Godot;
using Nocturnis.Enigmos.Boards;
using Nocturnis.Enigmos.Cables;
using Nocturnis.Enigmos.Modules;
using Nocturnis.Enigmos.Modules.InterlayerModules;
using Nocturnis.Enigmos.Ports;
using Nocturnis.GlobalManagement.Controls;
using Nocturnis.GlobalManagement.Providers;
using Nocturnis.Inventories.Items;
using Nocturnis.Inventories.Items.Items;
using Nocturnis.UIElements;
using Nocturnis.UIElements.Layers;
namespace Enigmos.Boards;
public abstract partial class BaseBoard : Panel, IBaseBoard
{
public bool CableVisualMode { get; set; }
public bool LabelVisualMode { get; set; }
public HashSet<IBaseCable> FocusedCables { get; set; } = new();
public void SetCableVisualMode(bool mode)
{
CableVisualMode = mode;
foreach (BaseCable cable in GetChildren().OfType<BaseCable>())
cable.Modulate = Color.Color8(255, 255, 255, (Byte)(mode ? 20 : 255));
}
public void SetLabelVisualMode(bool mode)
{
LabelVisualMode = mode;
foreach (BaseModule module in GetChildren().OfType<BaseModule>())
if(module.HasLabel)
module.Label!.Visible = !mode;
}
public void AddCable(IBaseCable cable)
{
AddChild(cable.AsNode);
cable.Modulate = Color.Color8(255, 255, 255, (Byte)(CableVisualMode ? 20 : 255));
}
public IModuleManualLayer ModuleManualLayer { get; set; }
public bool ManualOpened { get; set; }
protected HashSet<IBaseModule> Modules { get; set; } = new();
protected IEnumerable<ProgrammableModule> ProgrammableModules() =>
Modules
.OfType<ProgrammableModule>();
public IEnumerable<ITerminalModule> TerminalModules =>
Modules
.OfType<ITerminalModule>()
.Union(ProgrammableModules().SelectMany(module => module.UnderlyingBoard!.TerminalModules));
public IPanelViewer PanelViewer { get; set; }
public Dictionary<IBasePort, IBaseCable> CablePairing { get; set; } = new();
public IEnumerable<IBasePort> OnBoardPorts
{
get
{
IEnumerable<IBasePort> res = Array.Empty<IBasePort>();
foreach (IInterlayerModule im in GetChildren().OfType<IInterlayerModule>())
res = res.Union(im.Ports);
return res;
}
}
public IBasePort ConnectPending { get; set; }
public IBoardControlLayer CircuitBoardControlLayer { get; set; }
public IModuleMovingLayer ModuleMovingLayer { get; set; }
public virtual void Init()
{
CablePairing = new Dictionary<IBasePort, IBaseCable>();
Modules = new HashSet<IBaseModule>();
FocusedCables = new HashSet<IBaseCable>();
ConnectPending = null;
ModuleManualLayer = GetNode<IModuleManualLayer>("ModuleManualLayer");
ModuleMovingLayer = GetNode<IModuleMovingLayer>("ModuleMovingLayer");
ModuleMovingLayer.Board = this;
PanelViewer = GetNode<IPanelViewer>("PanelViewer");
CircuitBoardControlLayer = GetNode<IBoardControlLayer>("CircuitBoardControlLayer");
CircuitBoardControlLayer.Board = this;
}
protected virtual void AddModule(IBaseModule module, Vector2 pos)
{
module.Board = this;
AddChild(module.AsNode);
if (module is ICompositeModule compositeModule)
foreach (IBaseModule subModule in compositeModule.SubModules)
subModule.Board = this;
module.Position = pos;
Modules.Add(module);
}
public virtual void Reset()
{
foreach (ISourceModule sm in Modules.OfType<ISourceModule>())
sm.Reset();
foreach (IProgrammableModule pm in Modules.OfType<IProgrammableModule>())
pm.Board!.Reset();
foreach (IControllingModule cm in Modules.OfType<IControllingModule>())
cm.Visited = false;
/*
foreach (IBaseModule module in Modules)
{
if (module is RootModule rootModule)
rootModule.ActionFinished = false;
if (module is ICompositeModule compositeModule)
{
foreach (IBaseModule subModule in compositeModule.SubModules())
{
foreach (DataOutPort port in subModule.Ports.OfType<DataOutPort>())
{
port.DataUpdated = false;
}
}
}
if (module is ProgrammableModule programmableModule)
{
programmableModule.UnderlyingBoard!.Reset();
foreach (DataOutPort outPort in programmableModule.ExplicitPorts.OfType<DataOutPort>())
outPort.DataUpdated = false;
foreach (DataOutPort outPort in programmableModule.ImplicitPorts.OfType<DataOutPort>())
outPort.DataUpdated = false;
}
if (module is PiplineModule controllingModule)
controllingModule.Visited = false;
if (module is TerminalModule terminalModule)
terminalModule.Finished = false;
foreach (DataOutPort port in module.Ports.OfType<DataOutPort>())
port.DataUpdated = false;
}*/
}
public override bool _CanDropData(Vector2 atPosition, Variant data)
{
VariantWithType vData = data.As<VariantWithType>();
if (vData.TypeHint != "Module")
{
if(vData.TypeHint != "Item")
return false;
IBaseItem item = vData.UnderlyingData.As<Node>() as IBaseItem;
if (item is IBaseModuleItem moduleItem)
{
foreach (IBaseModule module in Modules)
if (GlobalProvider.UIProvider!.Overlap(atPosition, moduleItem.ContentModule.Size, module.Position, module.Size))
return false;
return true;
}
return false;
}
BaseModule? moduleData = vData.UnderlyingData.As<BaseModule?>();
if (moduleData == null)
return false;
Vector2 pos = atPosition - moduleData.PivotOffset;
foreach (IBaseModule module in Modules)
{
if(module == moduleData)
continue;
if (GlobalProvider.UIProvider.Overlap(pos, moduleData.Size, module.Position, module.Size))
return false;
}
return true;
}
public override void _DropData(Vector2 atPosition, Variant data)
{
VariantWithType vData = data.As<VariantWithType>();
if(vData.TypeHint == "Module")
{
BaseModule vModule = vData.UnderlyingData.As<BaseModule>();
vModule.Position = atPosition - vModule.PivotOffset;
vModule.UpdateCables();
}
else
{
IBaseModuleItem moduleItem = vData.UnderlyingData.As<Node>() as IBaseModuleItem;
AddModule(moduleItem.ContentModule, atPosition);
ItemDraggingControl.Instance.DraggingFrom!.Item = null;
}
}
protected T GetModule<T>(NodePath path) where T : BaseModule
{
T res = GetNode<T>(path);
res.Init();
Modules.Add(res);
res.Board = this;
return res;
}
public T[] GetModules<T>() where T : BaseModule
{
T[] res = GetChildren().OfType<T>().OrderBy(x => x.Name).ToArray();
foreach (T m in res)
{
m.Init();
Modules.Add(m);
m.Board = this;
}
return res;
}
}