|
| 1 | +package com.kneelawk.graphlib.v3.api.datastructure; |
| 2 | + |
| 3 | +import java.util.Objects; |
| 4 | + |
| 5 | +// Translated from 2xsaiko's HCTM-Base Graph code: |
| 6 | +// https://github.com/2xsaiko/hctm-base/blob/119df440743543b8b4979b450452d73f2c3c4c47/src/main/kotlin/common/graph/Graph.kt |
| 7 | + |
| 8 | +/** |
| 9 | + * Link in a general purpose graph data structure. |
| 10 | + * <p> |
| 11 | + * This link is non-directional. A link from node 'A' to node 'B' is equal to a link from node 'B' to node 'A'. This is |
| 12 | + * upheld in this type's {@link #equals(Object)} and {@link #hashCode()}. |
| 13 | + * <p> |
| 14 | + * If a link needs to be directional, then its data should reference one of the nodes, making it asymmetrical. |
| 15 | + * Referencing a node can be done with a {@link com.kneelawk.graphlib.v3.api.pos.NodePos}. |
| 16 | + * |
| 17 | + * @param first the first node in this link. |
| 18 | + * @param second the second node in this link. |
| 19 | + * @param key the key that makes this link unique out of all the links between the same two nodes. |
| 20 | + * @param <K> the type of key used to index each node. |
| 21 | + * @param <L> the type of link data contained in this link. |
| 22 | + */ |
| 23 | +public record KeyedLink<K, L>(KeyedNode<K, L> first, KeyedNode<K, L> second, L key) { |
| 24 | + /** |
| 25 | + * Checks to see if the given node is either of the two nodes in this link. |
| 26 | + * |
| 27 | + * @param node the node to check. |
| 28 | + * @return <code>true</code> if the given node is either of the nodes in this link. |
| 29 | + */ |
| 30 | + public boolean contains(KeyedNode<K, L> node) { |
| 31 | + return Objects.equals(first, node) || Objects.equals(second, node); |
| 32 | + } |
| 33 | + |
| 34 | + /** |
| 35 | + * Checks to see if the given key is for either of the two nodes in this link. |
| 36 | + * |
| 37 | + * @param key the key to check. |
| 38 | + * @return <code>true</code> if a node with the given key is wither of the nodes in this link. |
| 39 | + */ |
| 40 | + public boolean contains(K key) { |
| 41 | + return Objects.equals(first.key(), key) || Objects.equals(second.key(), key); |
| 42 | + } |
| 43 | + |
| 44 | + /** |
| 45 | + * Gets the node opposite the given node. |
| 46 | + * |
| 47 | + * @param node the node to get the other end of the link from. |
| 48 | + * @return the node at the other end of the link from the given node. |
| 49 | + */ |
| 50 | + public KeyedNode<K, L> other(KeyedNode<K, L> node) { |
| 51 | + if (Objects.equals(first, node)) { |
| 52 | + return second; |
| 53 | + } else { |
| 54 | + return first; |
| 55 | + } |
| 56 | + } |
| 57 | + |
| 58 | + /** |
| 59 | + * Gets the node opposite the node with the given key. |
| 60 | + * |
| 61 | + * @param key the key of the node to get the other end of hte link from. |
| 62 | + * @return the node at the other end of the link from the node with the given key. |
| 63 | + */ |
| 64 | + public KeyedNode<K, L> other(K key) { |
| 65 | + if (Objects.equals(first.key(), key)) { |
| 66 | + return second; |
| 67 | + } else { |
| 68 | + return first; |
| 69 | + } |
| 70 | + } |
| 71 | + |
| 72 | + @Override |
| 73 | + public boolean equals(Object o) { |
| 74 | + if (this == o) return true; |
| 75 | + if (o == null || getClass() != o.getClass()) return false; |
| 76 | + |
| 77 | + KeyedLink<?, ?> linkKey = (KeyedLink<?, ?>) o; |
| 78 | + |
| 79 | + if (!key.equals(linkKey.key)) return false; |
| 80 | + |
| 81 | + // note: hashCode and equals are symmetrical regardless of node order |
| 82 | + if (first.equals(linkKey.first)) { |
| 83 | + return second.equals(linkKey.second); |
| 84 | + } else if (second.equals(linkKey.first)) { |
| 85 | + return first.equals(linkKey.second); |
| 86 | + } |
| 87 | + |
| 88 | + return false; |
| 89 | + } |
| 90 | + |
| 91 | + @Override |
| 92 | + public int hashCode() { |
| 93 | + // note: hashCode and equals are symmetrical regardless of node order |
| 94 | + int result = first.hashCode(); |
| 95 | + result = result ^ second.hashCode(); |
| 96 | + result = 31 * result + key.hashCode(); |
| 97 | + return result; |
| 98 | + } |
| 99 | + |
| 100 | + @Override |
| 101 | + public String toString() { |
| 102 | + return "link(" + first + " <-> " + second + ", " + key + ')'; |
| 103 | + } |
| 104 | +} |
0 commit comments