147 lines
3.7 KiB
C#
Executable File
147 lines
3.7 KiB
C#
Executable File
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Godot;
|
|
using VirtualChemistry.Chemistry.Atoms.Implements;
|
|
using VirtualChemistry.Chemistry.Atoms.Resolver;
|
|
using VirtualChemistry.Chemistry.Bonds.Implements;
|
|
using VirtualChemistry.Chemistry.Compounds.Implements;
|
|
using VirtualChemistry.Chemistry.Mixtures.Implements;
|
|
|
|
public partial class CompoundConstructor : Panel
|
|
{
|
|
private HeterogeneousMixture HeterogeneousMixture { get; set; }
|
|
public HomogeneousMixture HomogeneousMixture { get; set; }
|
|
public HashSet<Atom> Atoms { get; set; } = new();
|
|
public BaseBond ConnectPending { get; set; } = BaseBond.Null;
|
|
public Atom PendingAtom { get; set; }
|
|
public Dictionary<Atom, HashSet<Bond>> BondMap { get; set; } = new();
|
|
|
|
// Called when the node enters the scene tree for the first time.
|
|
public override void _Ready()
|
|
{
|
|
GlobalScene.CompoundConstructor = this;
|
|
HeterogeneousMixture = new();
|
|
HomogeneousMixture = HeterogeneousMixture.AddLayer();
|
|
}
|
|
|
|
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
public override void _Process(double delta)
|
|
{
|
|
}
|
|
|
|
public override bool _CanDropData(Vector2 atPosition, Variant data)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public override void _DropData(Vector2 atPosition, Variant data)
|
|
{
|
|
Atom a = data.As<Atom>();
|
|
a.Position = atPosition;
|
|
if(BondMap.ContainsKey(a))
|
|
foreach (Bond b in BondMap[a])
|
|
b.BondUpdate();
|
|
}
|
|
|
|
public void AddAtomOf(int idx)
|
|
{
|
|
BaseAtom a = AtomResolver.Resolve(idx);
|
|
Compound c = a.GrabCompound;
|
|
c.Amount = 1;
|
|
Atom at = ResourceLoader.Load<PackedScene>("res://Scenes/Atom.tscn").Instantiate<Atom>();
|
|
at.BaseAtom = a;
|
|
AddChild(at);
|
|
at.Position = new(500, 500);
|
|
HomogeneousMixture.AddCompound(c);
|
|
Atoms.Add(at);
|
|
}
|
|
|
|
public void RemoveAtomOf(Atom atom)
|
|
{
|
|
foreach (BaseBond b in atom.BaseAtom.ConnectedBonds)
|
|
b.Disconnect();
|
|
|
|
Bond[] toRemove = Array.Empty<Bond>();
|
|
if (BondMap.TryGetValue(atom, out HashSet<Bond> value))
|
|
toRemove = value.ToArray();
|
|
|
|
foreach (Bond b in toRemove)
|
|
{
|
|
BondMap[b.AtomFrom].Remove(b);
|
|
BondMap[b.AtomTo].Remove(b);
|
|
RemoveChild(b);
|
|
}
|
|
|
|
atom.BaseAtom.Compound.HomogeneousMixture.Compounds.Remove(atom.BaseAtom.Compound);
|
|
atom.BaseAtom.Compound.HomogeneousMixture = HomogeneousMixture.Null;
|
|
atom.BaseAtom.Compound = Compound.Null;
|
|
RemoveChild(atom);
|
|
Atoms.Remove(atom);
|
|
}
|
|
|
|
public void ConnectAtoms(Atom a, BaseBond b)
|
|
{
|
|
b.Connect(ConnectPending);
|
|
Bond bond = ResourceLoader.Load<PackedScene>("res://Scenes/Bond.tscn").Instantiate<Bond>();
|
|
bond.AtomFrom = PendingAtom;
|
|
bond.AtomTo = a;
|
|
bond.TypeA = ConnectPending.BondType;
|
|
bond.TypeB = b.BondType;
|
|
|
|
if (!BondMap.ContainsKey(a))
|
|
BondMap[a] = new HashSet<Bond>();
|
|
BondMap[a].Add(bond);
|
|
if (!BondMap.ContainsKey(PendingAtom!))
|
|
BondMap[PendingAtom] = new HashSet<Bond>();
|
|
BondMap[PendingAtom].Add(bond);
|
|
ConnectPending = BaseBond.Null;
|
|
a.AtomActions.BuildMenu();
|
|
PendingAtom.AtomActions.BuildMenu();
|
|
PendingAtom = null;
|
|
AddChild(bond);
|
|
bond.BondUpdate();
|
|
}
|
|
|
|
private void Back()
|
|
{
|
|
GlobalScene.MainScene.SwitchToDemo();
|
|
}
|
|
|
|
private void Build()
|
|
{
|
|
HeterogeneousMixture.Container = GlobalScene.Demo.SelectedBottle;
|
|
GlobalScene.Demo.SelectedBottle.Content = HeterogeneousMixture;
|
|
Clear();
|
|
}
|
|
|
|
private void Clear(bool save = true)
|
|
{
|
|
if (!save)
|
|
{
|
|
foreach (Atom atom in Atoms)
|
|
RemoveAtomOf(atom);
|
|
return;
|
|
}
|
|
|
|
HashSet<Bond> removedBonds = new();
|
|
foreach (Atom atom in Atoms)
|
|
{
|
|
RemoveChild(atom);
|
|
|
|
foreach (Bond bond in BondMap[atom])
|
|
{
|
|
if (!removedBonds.Contains(bond))
|
|
RemoveChild(bond);
|
|
removedBonds.Add(bond);
|
|
}
|
|
}
|
|
|
|
Atoms = new();
|
|
BondMap = new();
|
|
HeterogeneousMixture = new HeterogeneousMixture();
|
|
}
|
|
|
|
private void ForceClear() => Clear(false);
|
|
}
|