Files
Enigmos/Modules/BaseModule.cs
2024-06-29 06:35:23 +08:00

163 lines
5.6 KiB
C#

using Enigmos.Exceptions;
using Enigmos.Manual;
using Enigmos.Modules.ControllingModules;
using Enigmos.Ports;
using Godot;
using Nocturnis.DataStructures;
using Nocturnis.Enigmos.Boards;
using Nocturnis.Enigmos.Cables;
using Nocturnis.Enigmos.Modules;
using Nocturnis.Enigmos.Ports;
using Nocturnis.UIElements;
using TabulaSmaragdina;
namespace Enigmos.Modules;
public abstract partial class BaseModule : TextureRect, IBaseModule
{
private static readonly Font GnuUni = ResourceLoader.Load<Font>("res://Resources/Fonts/GnuUnifontFull-Pm9P.ttf");
[Export] private int PresetPortQuality { get; set; }
[Export] private int PresetPortCondition { get; set; }
[Export] protected bool UsingPreset { get; set; }
[Export] public IPresetModuleConnection[] PresetConnections { get; set; }
[Export] public string LabelString { get; set; } = "";
public virtual Vector2 PositionToBoard => Position;
protected virtual bool Draggable() => true;
protected virtual bool HasManual() => true;
public bool HasLabel() => HasManual();
public virtual IEnumerable<IBasePort> Ports => Array.Empty<BasePort>();
public IBaseBoard? Board { get; set; }
private ModuleManual? Manual { get; set; }
public ISimpleLabel? Label { get; set; }
public Node AsNode => this;
public virtual void PresetValueInit()
{
foreach (IBasePort port in Ports)
{
port.Condition = PresetPortCondition;
port.Quality = PresetPortQuality;
}
}
public virtual void Init()
{
if (HasLabel())
{
Label = GlobalProvider.SceneProvider
.AssetMapper<ISimpleLabel>()
.Instantiate<ISimpleLabel>();
Label.Position = new Vector2(0, -25);
Label.Text = LabelString;
AddChild(Label.AsNode);
}
}
/// <summary>
/// Used to determine result of fixing a port with given material
/// </summary>
public virtual double MaintenanceAlpha => 0d;
/// <summary>
/// Used to determine result of fixing a port with given material
/// </summary>
public virtual double MaintenanceBeta => 0d;
public virtual string GetDescription => "";
public virtual void UpdateCables()
{
foreach (IBasePort port in Ports)
{
if(!Board!.CablePairing.ContainsKey(port))
continue;
Board.CablePairing[port].LineUpdate();
}
}
protected virtual void PostInit()
{
foreach (IBasePort port in Ports)
port.Module = this;
if(UsingPreset)
PresetValueInit();
}
protected virtual void TimeoutCheck(RootModule root)
{
if (root.Timer.ElapsedMilliseconds < 25) return;
root.Timer.Stop();
throw ModuleExecutionTimeout.Exception;
}
protected virtual void TimeoutHandler(ModuleExecutionTimeout timeout) => throw timeout;
public override Variant _GetDragData(Vector2 atPosition)
{
if (!Draggable())
return default;
Board!.ModuleMovingLayer.DraggingModule = this;
Board!.ModuleMovingLayer.MouseOffset = GetLocalMousePosition();
return GlobalProvider.DataStructureProvider.NewVariantWithType("Module", this);
}
protected T GetPort<T>(string path) where T : BasePort
{
T res = GetNode<T>(path);
res.Init();
return res;
}
public override void _Input(InputEvent @event)
{
if (@event is InputEventMouseButton eventMouseButton)
{
Vector2 mousePosition = GetLocalMousePosition();
if(mousePosition.X > 0 && mousePosition.X < Size.X && mousePosition.Y > 0 && mousePosition.Y < Size.Y)
{
if (eventMouseButton.ButtonIndex == MouseButton.Right && eventMouseButton.Pressed)
{
if (!HasManual())
return;
if (Board.ManualOpened)
return;
if (Manual == null)
{
Manual = GlobalProvider.SceneProvider
.AssetMapper<ModuleManual>()
.Instantiate<ModuleManual>();
Manual.Init(this);
}
Board.ModuleManualLayer.AddChild(Manual);
Manual.Position = Board.ModuleManualLayer.ManualPosition.Position - Manual.Size / 2;
Board.ManualOpened = true;
return;
}
if (eventMouseButton.ButtonIndex == MouseButton.Left && eventMouseButton.Pressed)
{
if (Board!.CableVisualMode)
{
foreach (IBaseCable cable in Board.FocusedCables)
cable.Modulate = Color.Color8(255, 255, 255, 20);
Board.FocusedCables = Ports
.Where(Board.CablePairing.ContainsKey)
.Select(p => Board.CablePairing[p])
.ToHashSet();
if (this is ICompositeModule thisCompositeModule)
foreach (IBasePort port in thisCompositeModule.SubModules().SelectMany(module => module.Ports).Where(Board.CablePairing.ContainsKey))
Board.FocusedCables.Add(Board.CablePairing[port]);
foreach (IBaseCable cable in Board.FocusedCables)
cable.Modulate = Color.Color8(255, 255, 255, 255);
}
}
}
}
base._Input(@event);
}
}