Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added interfaces for various classes #84

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions NetPrints/Base/INode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using NetPrints.Core;

namespace NetPrints.Base
{
/// <summary>
/// Interface for all node types.
/// </summary>
public interface INode
{
/// <summary>
/// All pins on this node.
/// </summary>
public ObservableRangeCollection<INodePin> Pins { get; }

/// <summary>
/// Name of this node.
/// </summary>
public string Name { get; set; }

/// <summary>
/// Graph this node is contained in.
/// </summary>
public INodeGraph Graph
{
get;
}
}
}
10 changes: 10 additions & 0 deletions NetPrints/Base/INodeDataPin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using NetPrints.Core;
using NetPrints.Graph;

namespace NetPrints.Base
{
public interface INodeDataPin : INodePin
{
public ObservableValue<BaseType> PinType { get; }
}
}
6 changes: 6 additions & 0 deletions NetPrints/Base/INodeExecutionPin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace NetPrints.Base
{
public interface INodeExecutionPin : INodePin
{
}
}
15 changes: 15 additions & 0 deletions NetPrints/Base/INodeGraph.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using NetPrints.Core;

namespace NetPrints.Base
{
public interface INodeGraph
{
/// <summary>
/// List of nodes in this graph.
/// </summary>
public ObservableRangeCollection<INode> Nodes
{
get;
}
}
}
10 changes: 10 additions & 0 deletions NetPrints/Base/INodeInputPin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using NetPrints.Core;
using System.Collections.ObjectModel;

namespace NetPrints.Base
{
public interface INodeInputPin : INodePin
{
public IObservableCollectionView<INodeOutputPin> IncomingPins { get; }
}
}
10 changes: 10 additions & 0 deletions NetPrints/Base/INodeOutputPin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using NetPrints.Core;
using System.Collections.ObjectModel;

namespace NetPrints.Base
{
public interface INodeOutputPin : INodePin
{
public IObservableCollectionView<INodeInputPin> OutgoingPins { get; }
}
}
29 changes: 29 additions & 0 deletions NetPrints/Base/INodePin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using NetPrints.Core;

namespace NetPrints.Base
{
public enum NodePinConnectionType
{
Single,
Multiple
}

/// <summary>
/// Interface for node pins.
/// </summary>
public interface INodePin
{
/// <summary>
/// Name of the pin.
/// </summary>
public string Name { get; }

/// <summary>
/// Node this pin is contained in.
/// </summary>
public INode Node { get; }

public NodePinConnectionType ConnectionType { get; }
public ObservableRangeCollection<INodePin> ConnectedPins { get; }
}
}
10 changes: 10 additions & 0 deletions NetPrints/Base/INodeTypePin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using NetPrints.Core;
using NetPrints.Graph;

namespace NetPrints.Base
{
public interface INodeTypePin : INodePin
{
public ObservableValue<BaseType> InferredType { get; }
}
}
128 changes: 128 additions & 0 deletions NetPrints/Core/FilteredObservableCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;

namespace NetPrints.Core
{
public interface IObservableCollectionView<T> : IReadOnlyList<T>, INotifyCollectionChanged
{
public bool Contains(T item);

public int IndexOf(T item);
}

public class FilteredObservableCollection<TFiltered, TOriginal> : IObservableCollectionView<TFiltered> where TFiltered : TOriginal
{
public event NotifyCollectionChangedEventHandler CollectionChanged;

private readonly ObservableCollection<TOriginal> original;
private readonly Func<TFiltered, bool> filter;

private readonly List<TFiltered> subset;

public int Count => subset.Count;

TFiltered IReadOnlyList<TFiltered>.this[int index] => subset[index];

public TFiltered this[int index] => subset[index];

public FilteredObservableCollection(ObservableCollection<TOriginal> original, Func<TFiltered, bool> filter)
{
Debug.Assert(original != null, "Original collection was null.");
Debug.Assert(filter != null, "Filter was null.");

this.original = original;
this.filter = filter;

original.CollectionChanged += OnOriginalCollectionChanged;

subset = original.OfType<TFiltered>().Where(item => filter(item)).ToList();
}

public static FilteredObservableCollection<TFiltered, TOriginal> TypeFilter(ObservableCollection<TOriginal> original)
{
return new FilteredObservableCollection<TFiltered, TOriginal>(original, item => item is TFiltered);
}

private void OnOriginalCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
subset.Clear();
CollectionChanged?.Invoke(sender, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));

subset.AddRange(original.OfType<TFiltered>().Where(item => filter(item)));
CollectionChanged?.Invoke(sender, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, subset, 0));

// TODO: Handle inserts / replace correctly.

/*if (e.Action != NotifyCollectionChangedAction.Reset)
{
List<TFiltered> oldItems = null, newItems = null;
int oldIndex = -1;

// Remove old items
if (e.OldItems != null)
{
oldIndex = IndexOf(e.OldItems.OfType<TFiltered>().Last());
oldItems = e.OldItems.OfType<TFiltered>().Where(item => subset.Remove(item)).ToList();
}

// Add new items if filter applies
if (e.NewItems != null)
{
newItems = e.NewItems.OfType<TFiltered>().Where(item => filter(item)).ToList();

foreach (var newItem in newItems)
{
subset.Add(newItem);
}
}

// Trigger collection change event if any items were added or removed.
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
if (newItems != null && newItems.Count > 0)
{
CollectionChanged?.Invoke(sender, new NotifyCollectionChangedEventArgs(e.Action, newItems, subset.Count - newItems.Count));
}
break;
case NotifyCollectionChangedAction.Remove:
if (oldItems != null && oldItems.Count > 0)
{
CollectionChanged?.Invoke(sender, new NotifyCollectionChangedEventArgs(e.Action, oldItems, oldIndex));
}
break;
case NotifyCollectionChangedAction.Replace:
if ((oldItems != null && oldItems.Count > 0) || (newItems != null && newItems.Count > 0))
{
CollectionChanged?.Invoke(sender, new NotifyCollectionChangedEventArgs(e.Action, oldItems, newItems));
}
break;
default:
throw new NotImplementedException();
}

}
else
{
if (subset.Count > 0)
{
subset.Clear();
CollectionChanged?.Invoke(sender, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}*/
}

public IEnumerator<TFiltered> GetEnumerator() => subset.GetEnumerator();

IEnumerator IEnumerable.GetEnumerator() => subset.GetEnumerator();

public bool Contains(TFiltered item) => subset.Contains(item);

public int IndexOf(TFiltered item) => subset.IndexOf(item);
}
}
126 changes: 126 additions & 0 deletions NetPrints/Core/GraphConnectionTracker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
using NetPrints.Base;
using NetPrints.Graph;
using System.Collections.Specialized;
using System.Linq;

namespace NetPrints.Core
{
public class GraphConnectionTracker
{
public ObservableRangeCollection<PinConnection> Connections { get; private set; }

private INodeGraph graph;

public GraphConnectionTracker(INodeGraph graph)
{
this.graph = graph;

SetupInitialConnections();
}

private void SetupInitialConnections()
{
if (Connections is null)
{
Connections = new ObservableRangeCollection<PinConnection>();
}

OnNodeCollectionChanged(null, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, graph.Nodes, 0));
graph.Nodes.CollectionChanged += OnNodeCollectionChanged;
}

private void OnNodeCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.OldItems != null)
{
foreach (var node in e.OldItems.Cast<INode>())
{
SetupNodeEvents(node, false);
}
}

if (e.NewItems != null)
{
foreach (var node in e.NewItems.Cast<INode>())
{
SetupNodeEvents(node, true);
}
}
}

private void OnNodePinsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.OldItems != null)
{
foreach (var pin in e.OldItems.Cast<NodePin>())
{
SetupPinEvents(pin, false);
}
}

if (e.NewItems != null)
{
foreach (var pin in e.NewItems.Cast<NodePin>())
{
SetupPinEvents(pin, true);
}
}
}

private void OnPinConnectionsCollectionChanged(NodePin fromPin, object sender, NotifyCollectionChangedEventArgs e)
{
if (e.OldItems != null)
{
var removedConnections = Connections.Where(conn =>
(conn.PinA == fromPin && e.OldItems.Contains(conn.PinB))
|| (conn.PinB == fromPin && e.OldItems.Contains(conn.PinA)))
.ToArray();

Connections.RemoveRange(removedConnections);
}

if (e.NewItems != null)
{
Connections.AddRange(e.NewItems.Cast<NodePin>()
.Where(pin => pin.ConnectionType == NodePinConnectionType.Single)
.Select(toPin => new PinConnection(fromPin, toPin)));
}
}

private void SetupNodeEvents(INode node, bool add)
{
if (!add)
{
node.Pins.CollectionChanged -= OnNodePinsCollectionChanged;
}

foreach (var pin in node.Pins.Cast<NodePin>())
{
SetupPinEvents(pin, add);
}

if (add)
{
node.Pins.CollectionChanged += OnNodePinsCollectionChanged;
}
}

private void SetupPinEvents(NodePin pin, bool add)
{
if (add)
{
if (pin.ConnectionType == NodePinConnectionType.Single)
{
Connections.AddRange(pin.ConnectedPins.Select(toPin => new PinConnection((NodePin)pin, (NodePin)toPin)));
}

pin.ConnectedPins.CollectionChanged += (object sender, NotifyCollectionChangedEventArgs e) => OnPinConnectionsCollectionChanged(pin, sender, e);
}
else
{
//pin.ConnectedPins.CollectionChanged -= (object sender, NotifyCollectionChangedEventArgs e) => OnPinConnectionsCollectionChanged(pin, sender, e);
Connections.RemoveRange(Connections.Where(conn => conn.PinA == pin || conn.PinB == pin).ToArray());
}
}
}
}
8 changes: 8 additions & 0 deletions NetPrints/Core/INodeInputButtons.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace NetPrints.Core
{
public interface INodeInputButtons
{
public void InputPlusClicked();
public void InputMinusClicked();
}
}
8 changes: 8 additions & 0 deletions NetPrints/Core/INodeOutputButtons.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace NetPrints.Core
{
public interface INodeOutputButtons
{
public void OutputPlusClicked();
public void OutputMinusClicked();
}
}
Loading