Aetheria/Assets/Plugins/MSAGL/Layout/Layered/IntEdge.cs
Reinier Vens dbc522a224 Weapos Rejiggered
Modified weapon scripts to eliminate specialized projectile behavior - allows charged weapons to have projectiles and modify weapon stats when charged
Added machine gun weapon & VFX
Moved third party code to Plugins folder to improve compile times
2021-01-31 03:52:32 +00:00

353 lines
No EOL
10 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Msagl.Core.Geometry;
using Microsoft.Msagl.Core.Geometry.Curves;
using Microsoft.Msagl.Core.GraphAlgorithms;
using Microsoft.Msagl.Core.Layout;
namespace Microsoft.Msagl.Layout.Layered {
/// <summary>
/// An edge with source and target represented as integers, they point to an array of Nodes of the graph
/// </summary>
[SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
#if TEST_MSAGL
public
#else
internal
#endif
class IntEdge : IEnumerable<int>, IEdge {
int source;
/// <summary>
/// the source
/// </summary>
public int Source {
get { return source; }
#if SHARPKIT //https://code.google.com/p/sharpkit/issues/detail?id=289 Support Dictionary directly based on object's GetHashCode
set { source = value; UpdateHashKey(); }
#else
set { source = value; }
#endif
}
int target;
/// <summary>
/// the edge target
/// </summary>
public int Target {
get { return target; }
#if SHARPKIT //https://code.google.com/p/sharpkit/issues/detail?id=289 Support Dictionary directly based on object's GetHashCode
set { target = value; UpdateHashKey(); }
#else
set { target = value; }
#endif
}
bool reversed;
/// <summary>
/// An edge can be reversed to keep the graph acyclic
/// </summary>
public bool Reversed {
get { return reversed; }
// set { reversed = value; }
}
/// <summary>
/// A dummy edge that will not be drawn; serves just as a place holder.
/// </summary>
public bool IsVirtualEdge { get; set; }
/// <summary>
/// constructor
/// </summary>
/// <param name="source"></param>
/// <param name="target"></param>
internal IntEdge(int source, int target) {
this.source = source;
this.target = target;
#if SHARPKIT //https://code.google.com/p/sharpkit/issues/detail?id=289 Support Dictionary directly based on object's GetHashCode
UpdateHashKey();
#endif
}
/// <summary>
/// Returns true if the edge has label
/// </summary>
internal bool HasLabel {
get { return Edge.Label != null; }
}
/// <summary>
/// Label width
/// </summary>
internal double LabelWidth {
get { return Edge.Label.Width; }
}
/// <summary>
/// Label height
/// </summary>
internal double LabelHeight {
get { return Edge.Label.Height; }
}
/// <summary>
/// This function changes the edge by swapping
/// source and target. However Revert(Revert) does not change it.
/// </summary>
internal void Revert() {
int t = source;
source = target;
target = t;
reversed = !reversed;
#if SHARPKIT //https://code.google.com/p/sharpkit/issues/detail?id=289 Support Dictionary directly based on object's GetHashCode
UpdateHashKey();
#endif
}
/// <summary>
/// The original edge corresponding to the IntEdge
/// </summary>
public Edge Edge { get; set; }
/// <summary>
/// constructor
/// </summary>
/// <param name="source"></param>
/// <param name="target"></param>
/// <param name="edge"></param>
internal IntEdge(int source, int target, Edge edge) {
this.source = source;
this.target = target;
Edge = edge;
if (edge != null) {
Separation = edge.Separation;
Weight = edge.Weight;
}
#if SHARPKIT //https://code.google.com/p/sharpkit/issues/detail?id=289 Support Dictionary directly based on object's GetHashCode
UpdateHashKey();
#endif
}
/// <summary>
/// compares only source and target
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override bool Equals(object obj) {
var ie = obj as IntEdge;
if (ie == null)
return false;
return ie.source == source &&
ie.target == target;
}
#if SHARPKIT //https://code.google.com/p/sharpkit/issues/detail?id=289 Support Dictionary directly based on object's GetHashCode
private SharpKit.JavaScript.JsString _hashKey;
private void UpdateHashKey()
{
_hashKey = ""+source+","+target;
}
#endif
/// <summary>
///
/// </summary>
/// <returns></returns>
public override int GetHashCode() {
var hc = (uint) source.GetHashCode();
return (int) ((hc << 5 | hc >> 27) + (uint) target);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public override string ToString() {
return "Edge(" + source + "->" + target + ")";
}
internal ICurve Curve {
get { return Edge.Curve; }
set { Edge.Curve = value; }
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal SmoothedPolyline UnderlyingPolyline {
get { return Edge.UnderlyingPolyline; }
set { Edge.UnderlyingPolyline = value; }
}
int weight = 1;
internal int Weight {
get { return weight; }
set { weight = value; }
}
int crossingWeight = 1;
internal int CrossingWeight {
get { return crossingWeight; }
}
int separation;
/// <summary>
/// the distance between the source and the target in the number of layers
/// </summary>
public int Separation {
get { return separation; }
set { separation = value; }
}
/// <summary>
/// the edge span in layers
/// </summary>
public int LayerSpan {
get {
return layerEdges != null ? layerEdges.Length : 0;
// return virtualStart == -1 ? 1 : VirtualEnd - VirtualStart + 2;
}
}
LayerEdge[] layerEdges;
/// <summary>
///
/// </summary>
#if TEST_MSAGL
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public
#else
internal
#endif
IList<LayerEdge> LayerEdges {
get { return layerEdges; }
set { layerEdges = (LayerEdge[]) value; }
}
internal bool SelfEdge() {
return source == target;
}
internal IntEdge ReversedClone() {
var ret = new IntEdge(target, source, Edge);
if (layerEdges != null) {
int len = layerEdges.Length;
ret.layerEdges = new LayerEdge[len];
for (int i = 0; i < len; i++) {
LayerEdge le = layerEdges[len - 1 - i];
ret.layerEdges[i] = new LayerEdge(le.Target, le.Source, le.CrossingWeight);
}
ret.layerEdges[0].Source = target;
ret.layerEdges[layerEdges.Length - 1].Target = source;
}
#if SHARPKIT //https://code.google.com/p/sharpkit/issues/detail?id=289 Support Dictionary directly based on object's GetHashCode
ret.UpdateHashKey();
#endif
return ret;
}
internal LayerEdge this[int i] {
get { return layerEdges[i]; }
}
internal int Count {
get { return layerEdges.Length; }
}
internal void UpdateEdgeLabelPosition(Anchor[] anchors) {
if (Edge.Label != null) {
int m = layerEdges.Length/2;
LayerEdge layerEdge = layerEdges[m];
Routing.UpdateLabel(Edge, anchors[layerEdge.Source]);
}
}
#region IEnumerable<int> Members
/// <summary>
/// enumerates over virtual virtices corresponding to the original edge
/// </summary>
/// <returns></returns>
public IEnumerator<int> GetEnumerator() {
yield return layerEdges[0].Source;
foreach (LayerEdge le in layerEdges)
yield return le.Target;
}
#endregion
#region IEnumerable Members
IEnumerator IEnumerable.GetEnumerator() {
yield return layerEdges[0].Source;
foreach (LayerEdge le in layerEdges)
yield return le.Target;
}
#endregion
/// <summary>
/// The function returns an array arr such that
/// arr is a permutation of the graph vertices,
/// and for any edge e in graph if e.Source=arr[i]
/// e.Target=arr[j], then i is less than j
/// </summary>
/// <param name="graph"></param>
/// <returns></returns>
internal static int[] GetOrder(BasicGraph<IntEdge> graph){
var visited = new bool[graph.NodeCount];
//no recursion! So we have to organize a stack
var sv = new Stack<int>();
var se = new Stack<IEnumerator<int>>();
var order = new List<int>();
IEnumerator<int> en;
for (int u = 0; u < graph.NodeCount; u++){
if (visited[u])
continue;
int cu = u;
visited[cu] = true;
en = new Succ(graph, u).GetEnumerator();
do{
while (en.MoveNext()){
int v = en.Current;
if (!visited[v]){
visited[v] = true;
sv.Push(cu);
se.Push(en);
cu = v;
en = new Succ(graph, cu).GetEnumerator();
}
}
order.Add(cu);
if (sv.Count > 0){
en = se.Pop();
cu = sv.Pop();
}
else
break;
} while (true);
}
order.Reverse();
return order.ToArray();
}
}
}