diff --git a/Assets/Editor/ArchitectureInteractionEditor.cs b/Assets/Editor/ArchitectureInteractionEditor.cs
deleted file mode 100644
index 478a74d019..0000000000
--- a/Assets/Editor/ArchitectureInteractionEditor.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-using SEE.Game;
-using SEE.Game.City;
-using UnityEditor;
-using UnityEngine;
-
-#if UNITY_EDITOR
-
-namespace SEEEditor
-{
- ///
- /// Editor for ArchitectureInteraction.
- ///
- //[Obsolete("Introduced only for capturing videos.")]
- [CustomEditor(typeof(ArchitectureInteraction))]
- public class ArchitectureInteractionEditor : Editor
- {
- public override void OnInspectorGUI()
- {
- ArchitectureInteraction animator = target as ArchitectureInteraction;
-
- animator.CodeCity = (SEECity)EditorGUILayout.ObjectField
- (label: "Code City",
- obj: animator.CodeCity,
- objType: typeof(SEECity),
- allowSceneObjects: true);
-
- EditorGUILayout.BeginHorizontal();
- GUILayout.Label("Implementation Edges");
- {
- animator.ImplementationEdgesVisible = EditorGUILayout.Toggle(animator.ImplementationEdgesVisible);
- animator.ImplementationEdgesStartColor = EditorGUILayout.ColorField(animator.ImplementationEdgesStartColor);
- animator.ImplementationEdgesEndColor = EditorGUILayout.ColorField(animator.ImplementationEdgesEndColor);
- animator.ImplementationEdgesWidth = EditorGUILayout.FloatField(animator.ImplementationEdgesWidth);
- }
- EditorGUILayout.EndHorizontal();
-
- EditorGUILayout.BeginHorizontal();
- GUILayout.Label("Architecture Edges");
- {
- animator.ArchitectureEdgesVisible = EditorGUILayout.Toggle(animator.ArchitectureEdgesVisible);
- animator.ArchitectureEdgesStartColor = EditorGUILayout.ColorField(animator.ArchitectureEdgesStartColor);
- animator.ArchitectureEdgesEndColor = EditorGUILayout.ColorField(animator.ArchitectureEdgesEndColor);
- animator.ArchitectureEdgesWidth = EditorGUILayout.FloatField(animator.ArchitectureEdgesWidth);
- }
- EditorGUILayout.EndHorizontal();
-
- EditorGUILayout.BeginHorizontal();
- GUILayout.Label("Reflexion Edges");
- {
- animator.ReflexionEdgesVisible = EditorGUILayout.Toggle(animator.ReflexionEdgesVisible);
- animator.ReflexionEdgesWidth = EditorGUILayout.FloatField(animator.ReflexionEdgesWidth);
- }
- EditorGUILayout.EndHorizontal();
-
- EditorGUILayout.BeginHorizontal();
- {
- GUILayout.Label("Architecture Nodes");
- animator.ArchitectureNodesVisible = EditorGUILayout.Toggle(animator.ArchitectureNodesVisible);
- GUILayout.Label("Implementation Nodes");
- animator.ImplementationNodesVisible = EditorGUILayout.Toggle(animator.ImplementationNodesVisible);
- }
- EditorGUILayout.EndHorizontal();
-
- if (GUILayout.Button("Update"))
- {
- animator.UpdateCity();
- }
- }
- }
-}
-
-#endif
\ No newline at end of file
diff --git a/Assets/Resources/Materials/MirrorMaterial/Mirror Render Texture.renderTexture b/Assets/Resources/Materials/MirrorMaterial/Mirror Render Texture.renderTexture
index 1f8372e532..a213549bee 100644
--- a/Assets/Resources/Materials/MirrorMaterial/Mirror Render Texture.renderTexture
+++ b/Assets/Resources/Materials/MirrorMaterial/Mirror Render Texture.renderTexture
@@ -26,6 +26,7 @@ RenderTexture:
m_UseDynamicScale: 0
m_BindMS: 0
m_EnableCompatibleFormat: 1
+ m_EnableRandomWrite: 0
m_TextureSettings:
serializedVersion: 2
m_FilterMode: 1
diff --git a/Assets/SEE/Controls/Actions/AcceptDivergenceAction.cs b/Assets/SEE/Controls/Actions/AcceptDivergenceAction.cs
new file mode 100644
index 0000000000..45197890f9
--- /dev/null
+++ b/Assets/SEE/Controls/Actions/AcceptDivergenceAction.cs
@@ -0,0 +1,263 @@
+using System.Collections.Generic;
+using SEE.DataModel.DG;
+using SEE.Tools.ReflexionAnalysis;
+using SEE.GO;
+using SEE.Utils;
+using UnityEngine;
+using System;
+using SEE.Game.SceneManipulation;
+using SEE.Net.Actions;
+using SEE.Audio;
+using SEE.Game;
+
+namespace SEE.Controls.Actions
+{
+ ///
+ /// Action to solve a divergence (see ) between
+ /// implementation and architecture by adding the exact edge to the architecture that solves
+ /// this divergence.
+ ///
+ internal class AcceptDivergenceAction : AbstractPlayerAction
+ {
+ ///
+ /// Returns a new instance of .
+ ///
+ /// new instance
+ public static ReversibleAction CreateReversibleAction()
+ {
+ return new AcceptDivergenceAction();
+ }
+
+ ///
+ /// Returns a new instance of as a .
+ ///
+ /// new instance
+ public override ReversibleAction NewInstance()
+ {
+ return CreateReversibleAction();
+ }
+
+ ///
+ /// The graph that the edge which was hit by the user to be accepted into the graph is
+ /// in. Set in .
+ ///
+ private ReflexionGraph graph;
+
+ ///
+ /// The information required to (re-)create the edge that solves the divergence.
+ ///
+ private struct Memento
+ {
+ ///
+ /// The source of the edge.
+ ///
+ public Node from;
+ ///
+ /// The target of the edge.
+ ///
+ public Node to;
+ ///
+ /// The type of the edge.
+ ///
+ public string type;
+ ///
+ /// Construct a new memento.
+ ///
+ /// the source node of the edge in the architecture graph
+ /// the target node of the edge in the architecture grpah
+ public Memento(Node source, Node target, string type)
+ {
+ this.from = source;
+ this.to = target;
+ this.type = type;
+ }
+ }
+
+ ///
+ /// The information required to (re-)create the edge that solves the divergence.
+ ///
+ private Memento memento;
+
+ ///
+ /// The edge created by this action. Can be null if no edge has been created yet or whether
+ /// an Undo was called. The created edge is stored only to delete it again if Undo is
+ /// called. All information to create the edge is kept in .
+ ///
+ private Edge createdEdge;
+
+ ///
+ /// Registers itself at to listen for hovering events.
+ ///
+ public override void Start()
+ {
+ InteractableObject.LocalAnyHoverIn += LocalAnyHoverIn;
+ InteractableObject.LocalAnyHoverOut += LocalAnyHoverOut;
+ }
+
+ ///
+ /// Unregisters itself from . Does no longer listen for
+ /// hovering events.
+ ///
+ public override void Stop()
+ {
+ InteractableObject.LocalAnyHoverIn -= LocalAnyHoverIn;
+ InteractableObject.LocalAnyHoverOut -= LocalAnyHoverOut;
+ }
+
+ ///
+ /// See .
+ ///
+ /// true if completed
+ public override bool Update()
+ {
+ // indicates whether the divergence has been solved ("true" means "solved")
+ bool divergenceSolved = false;
+
+ // FIXME: Needs adaptation for VR where no mouse is available.
+ if (Input.GetMouseButtonDown(0)
+ && Raycasting.RaycastGraphElement(
+ out RaycastHit raycastHit,
+ out GraphElementRef _) != HitGraphElement.None)
+ {
+ // find the edge representing the divergence that should be solved.
+ GameObject selectedDivergenceEdge = raycastHit.collider.gameObject;
+
+ // check whether the object selected is an edge.
+ if (selectedDivergenceEdge.TryGetEdge(out Edge selectedEdge))
+ {
+ // check if the selected edge represents a divergence
+ if (selectedEdge.IsInImplementation() && ReflexionGraph.IsDivergent(selectedEdge))
+ {
+ // acquire the containing ReflexionGraph
+ graph = (ReflexionGraph)selectedEdge.ItsGraph;
+
+ // find that node in the architecture graph,
+ // which the divergence's source node is
+ // explicitly or implicitly mapped to
+ Node source = graph.MapsTo(selectedEdge.Source);
+
+ // find that node in the ArchitectureGraph,
+ // which the divergence's target is explicitly
+ // or implicitly mapped to
+ Node target = graph.MapsTo(selectedEdge.Target);
+
+ // we have both source and target of the edge and use a memento struct
+ // to remember which edge we have added
+ memento = new Memento(source, target, Edge.SourceDependency);
+
+ // create the edge
+ createdEdge = CreateEdge(memento);
+
+ // check whether edge creation was successfull
+ divergenceSolved = createdEdge != null;
+
+ // add audio cue to the appearance of the new architecture edge
+ AudioManagerImpl.EnqueueSoundEffect(IAudioManager.SoundEffect.NEW_EDGE_SOUND);
+
+ // update the current state depending on whether the divergence has been solved
+ // (required in order to register as an undo-able action)
+ currentState = divergenceSolved ? ReversibleAction.Progress.Completed : ReversibleAction.Progress.NoEffect;
+
+ // the selected object is synced and this action is done
+ return true;
+ }
+ }
+ else
+ {
+ Debug.LogWarning($"Selected Element {selectedDivergenceEdge.name} is not an edge.\n");
+ }
+ }
+ return false;
+ }
+
+ ///
+ /// Undoes this AcceptDivergenceAction.
+ ///
+ public override void Undo()
+ {
+ base.Undo();
+
+ // remove the synced edge (its info is saved in memento)
+ ReflexionGraph graph = (ReflexionGraph)createdEdge.ItsGraph;
+
+ if (graph != null)
+ {
+ // find the corresponding GameObject
+ GameObject createdEdgeGO = GraphElementIDMap.Find(createdEdge.ID);
+ // remove the edge's GameObject and graph representation locally and on the network
+ GameEdgeAdder.Remove(createdEdgeGO);
+
+ // propagate the new edge via network
+ new DeleteNetAction(createdEdge.ID).Execute();
+
+ // ensure the edge's GameObject gets destroyed properly
+ Destroyer.Destroy(createdEdgeGO);
+ }
+ else
+ {
+ throw new Exception($"Edge {createdEdge.ID} to be removed is not contained in a graph.");
+ }
+
+ // set any edge references back to null
+ createdEdge = null;
+ }
+
+ ///
+ /// Redoes this AcceptDivergenceAction.
+ ///
+ public override void Redo()
+ {
+ base.Redo();
+ // recreate the edge
+ createdEdge = CreateEdge(memento);
+ }
+
+ ///
+ /// Creates a new edge using the given . In case of any error, null will be
+ /// returned.
+ ///
+ /// information needed to create the edge
+ /// the new edge's GameObject and a reference to itself, or both null
+ private Edge CreateEdge(Memento memento)
+ {
+ Edge newEdge = AcceptDivergence.Accept(memento.from, memento.to, memento.type);
+
+ // propagate the edge (including matching ID) over network
+ new AcceptDivergenceNetAction(memento.from.ID, memento.to.ID, newEdge.ID, newEdge.Type).Execute();
+
+ return newEdge;
+ }
+
+ ///
+ /// Returns the of this action.
+ ///
+ ///
+ public override ActionStateType GetActionStateType()
+ {
+ return ActionStateTypes.AcceptDivergence;
+ }
+
+ ///
+ /// Returns all IDs of GameObjects manipulated by this action.
+ ///
+ /// all IDs of GameObjects manipulated by this action
+ public override HashSet GetChangedObjects()
+ {
+ if (createdEdge == null)
+ {
+ return new HashSet();
+ }
+ else
+ {
+ return new HashSet
+ {
+ memento.from.ID,
+ memento.to.ID,
+ createdEdge.ID
+ };
+ }
+ }
+ }
+}
diff --git a/Assets/SEE/Game/GameNodeScaler.cs.meta b/Assets/SEE/Controls/Actions/AcceptDivergenceAction.cs.meta
similarity index 83%
rename from Assets/SEE/Game/GameNodeScaler.cs.meta
rename to Assets/SEE/Controls/Actions/AcceptDivergenceAction.cs.meta
index a304f1b36a..c69154aa4a 100644
--- a/Assets/SEE/Game/GameNodeScaler.cs.meta
+++ b/Assets/SEE/Controls/Actions/AcceptDivergenceAction.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: a7be02c91dc83d3478cd70695ab975ad
+guid: 6c0170e2fab3a75bda98c1062700a9d2
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Assets/SEE/Controls/Actions/ActionStateType.cs b/Assets/SEE/Controls/Actions/ActionStateType.cs
index 20b5d48180..0cb5a51ccf 100644
--- a/Assets/SEE/Controls/Actions/ActionStateType.cs
+++ b/Assets/SEE/Controls/Actions/ActionStateType.cs
@@ -1,4 +1,4 @@
-using SEE.Utils;
+using SEE.Utils;
using UnityEngine;
namespace SEE.Controls.Actions
@@ -6,12 +6,6 @@ namespace SEE.Controls.Actions
///
/// The type of a state-based action.
- /// Implemented using the "Enumeration" (not enum) or "type safe enum" pattern.
- /// The following two pages have been used for reference:
- ///
- /// - https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/enumeration-classes-over-enum-types#implement-an-enumeration-base-class
- /// - https://ardalis.com/enum-alternatives-in-c/
- ///
///
public class ActionStateType : AbstractActionStateType
{
diff --git a/Assets/SEE/Controls/Actions/ActionStateTypes.cs b/Assets/SEE/Controls/Actions/ActionStateTypes.cs
index a1c9149dde..3c7b029180 100644
--- a/Assets/SEE/Controls/Actions/ActionStateTypes.cs
+++ b/Assets/SEE/Controls/Actions/ActionStateTypes.cs
@@ -111,6 +111,11 @@ static ActionStateTypes()
Color.magenta.Darker(), "Materials/ModernUIPack/Pencil",
DrawAction.CreateReversibleAction);
+ AcceptDivergence =
+ new("Accept Divergence", "Accept a diverging edge into the architecture",
+ Color.grey.Darker(), "Materials/ModernUIPack/Arrow Bold",
+ AcceptDivergenceAction.CreateReversibleAction);
+
// Metric Board actions
MetricBoard =
new("Metric Board", "Manipulate a metric board",
@@ -165,6 +170,7 @@ static ActionStateTypes()
parent: MetricBoard);
}
+
public readonly static ActionStateType Move;
public readonly static ActionStateType Rotate;
public readonly static ActionStateType Hide;
@@ -175,6 +181,7 @@ static ActionStateTypes()
public readonly static ActionStateType Delete;
public readonly static ActionStateType ShowCode;
public readonly static ActionStateType Draw;
+ public readonly static ActionStateType AcceptDivergence;
public readonly static ActionStateTypeGroup MetricBoard;
public readonly static ActionStateType AddBoard;
diff --git a/Assets/SEE/Controls/Actions/AddEdgeAction.cs b/Assets/SEE/Controls/Actions/AddEdgeAction.cs
index 4bf2a0bf7b..d13e5d0b22 100644
--- a/Assets/SEE/Controls/Actions/AddEdgeAction.cs
+++ b/Assets/SEE/Controls/Actions/AddEdgeAction.cs
@@ -7,6 +7,8 @@
using System;
using UnityEngine;
using SEE.Audio;
+using SEE.DataModel.DG;
+using SEE.Game.SceneManipulation;
namespace SEE.Controls.Actions
{
@@ -121,7 +123,7 @@ public override void Stop()
///
/// The default type of an added edge.
///
- private const string DefaultEdgeType = "Source_Dependency";
+ private const string DefaultEdgeType = Edge.SourceDependency;
///
/// .
diff --git a/Assets/SEE/Controls/Actions/AddNodeAction.cs b/Assets/SEE/Controls/Actions/AddNodeAction.cs
index 3179a77b5c..389b610b10 100644
--- a/Assets/SEE/Controls/Actions/AddNodeAction.cs
+++ b/Assets/SEE/Controls/Actions/AddNodeAction.cs
@@ -1,10 +1,10 @@
using System.Collections.Generic;
-using SEE.Game;
using SEE.GO;
using SEE.Net.Actions;
using SEE.Utils;
using UnityEngine;
using SEE.Audio;
+using SEE.Game.SceneManipulation;
namespace SEE.Controls.Actions
{
diff --git a/Assets/SEE/Controls/Actions/DeleteAction.cs b/Assets/SEE/Controls/Actions/DeleteAction.cs
index 3c583edd99..c3bc01ae11 100644
--- a/Assets/SEE/Controls/Actions/DeleteAction.cs
+++ b/Assets/SEE/Controls/Actions/DeleteAction.cs
@@ -1,12 +1,12 @@
using System.Collections.Generic;
using System.Linq;
-using SEE.Game;
using SEE.GO;
using SEE.Net.Actions;
using SEE.Utils;
using UnityEngine;
using UnityEngine.Assertions;
using SEE.Audio;
+using SEE.Game.SceneManipulation;
namespace SEE.Controls.Actions
{
diff --git a/Assets/SEE/Controls/Actions/MoveAction.cs b/Assets/SEE/Controls/Actions/MoveAction.cs
index 5097cc1942..eb0a624e71 100644
--- a/Assets/SEE/Controls/Actions/MoveAction.cs
+++ b/Assets/SEE/Controls/Actions/MoveAction.cs
@@ -4,6 +4,7 @@
using SEE.Game;
using SEE.Game.City;
using SEE.Game.Operator;
+using SEE.Game.SceneManipulation;
using SEE.Game.UI.Notification;
using SEE.GO;
using SEE.Net.Actions;
diff --git a/Assets/SEE/Controls/Interactables/InteractableObject.cs b/Assets/SEE/Controls/Interactables/InteractableObject.cs
index 4503a4731c..49417b07d8 100644
--- a/Assets/SEE/Controls/Interactables/InteractableObject.cs
+++ b/Assets/SEE/Controls/Interactables/InteractableObject.cs
@@ -9,7 +9,7 @@
#if INCLUDE_STEAM_VR
using Valve.VR.InteractionSystem;
#endif
-using SEE.Game;
+using SEE.Game.SceneManipulation;
using SEE.Net.Actions;
using SEE.Audio;
diff --git a/Assets/SEE/DataModel/DG/Edge.cs b/Assets/SEE/DataModel/DG/Edge.cs
index 29b393d3c0..81f16b7362 100644
--- a/Assets/SEE/DataModel/DG/Edge.cs
+++ b/Assets/SEE/DataModel/DG/Edge.cs
@@ -7,6 +7,28 @@ namespace SEE.DataModel.DG
///
public sealed class Edge : GraphElement
{
+ ///
+ /// The most general edge type for all dependencies extracted from the code.
+ /// This name must correspond to Axivion's nomenclatura.
+ ///
+ public const string SourceDependency = "Source_Dependency";
+
+ ///
+ /// Edge type for absences (reflexion analysis).
+ /// This name must correspond to Axivion's nomenclatura.
+ ///
+ public const string Absence = "Absence";
+ ///
+ /// Edge type for convergences (reflexion analysis).
+ /// This name must correspond to Axivion's nomenclatura.
+ ///
+ public const string Convergence = "Convergence";
+ ///
+ /// Edge type for divergences (reflexion analysis).
+ /// This name must correspond to Axivion's nomenclatura.
+ ///
+ public const string Divergence = "Divergence";
+
// IMPORTANT NOTES:
//
// If you use Clone() to create a copy of an edge, be aware that the clone
diff --git a/Assets/SEE/Game/ArchitectureInteraction.cs b/Assets/SEE/Game/ArchitectureInteraction.cs
deleted file mode 100644
index dac81784d5..0000000000
--- a/Assets/SEE/Game/ArchitectureInteraction.cs
+++ /dev/null
@@ -1,780 +0,0 @@
-using System.Collections.Generic;
-using SEE.DataModel.DG;
-using SEE.Game.City;
-using SEE.GO;
-using UnityEngine;
-
-namespace SEE.Game
-{
- ///
- /// This component is intended to provide interactions with a
- /// code city representing a reflexion model. One can show/hide nodes
- /// and edges in the architecture by user interactions.
- ///
- /// Its only purpose was to create a video. Do not use this class.
- ///
- [ExecuteAlways]
- public class ArchitectureInteraction : MonoBehaviour
- {
- ///
- /// The code city to be manipulated by this component.
- ///
- [Tooltip("The code city to be manipulated by this component.")]
- public SEECity CodeCity;
-
- //------------------
- // Edge types
- //------------------
-
- ///
- /// Edge types generated by the reflexion analysis.
- ///
- public static readonly HashSet ReflexionEdgeTypes = new HashSet()
- {
- "Absence",
- "Convergence",
- "Divergence",
- };
-
- ///
- /// Edge types representing implementation dependencies.
- ///
- public static readonly HashSet ArchitectureEdgeTypes = new HashSet()
- {
- "Source_Dependency",
- };
-
- public static readonly HashSet AllEdgeTypes = new HashSet();
-
- private HashSet implementationEdgeTypes = new HashSet();
- ///
- /// All edge types in the graph that are neither reflexion edges
- /// nor architecture dependencies.
- ///
- public HashSet ImplementationEdgeTypes
- {
- get
- {
- if (implementationEdgeTypes.Count == 0)
- {
- implementationEdgeTypes = GetImplementationEdgeTypes();
- foreach (string type in implementationEdgeTypes)
- {
- Debug.LogFormat("implementation edge type {0}\n", type);
- }
- }
- return implementationEdgeTypes;
- }
- }
-
- ///
- /// Returns all edge types in the graph that are neither reflexion edges
- /// nor architecture dependencies.
- ///
- /// all implementation edge types
- private HashSet GetImplementationEdgeTypes()
- {
- HashSet result = new HashSet();
- foreach (GameObject go in GetAllEdges())
- {
- string type = GetGraphEdge(go).Type;
- if (!ReflexionEdgeTypes.Contains(type) && !ArchitectureEdgeTypes.Contains(type))
- {
- result.Add(type);
- }
- }
- return result;
- }
-
- // -----------------------
- // Edge property defaults
- // -----------------------
- private static readonly Color implementationEdgesColorDefault = Color.black;
- private static readonly Color architectureEdgesColorDefault = Color.blue;
- private static readonly float implementationEdgeWidthDefault = 0.001f;
- private static readonly float architectureEdgeWidthDefault = 0.005f;
- private static readonly float reflexionEdgeWidthDefault = 0.005f;
-
- ///
- /// Resets the settings to their defaults. Called in editor mode when the
- /// user resets the component.
- ///
- private void Reset()
- {
- implementationEdgesVisible = false;
- implementationEdgesStartColor = Lighter(implementationEdgesColorDefault);
- implementationEdgesEndColor = implementationEdgesColorDefault;
- implementationEdgesWidth = implementationEdgeWidthDefault;
-
- architectureEdgesVisible = false;
- architectureEdgesStartColor = Lighter(architectureEdgesColorDefault);
- architectureEdgesEndColor = architectureEdgesColorDefault;
- architectureEdgesWidth = architectureEdgeWidthDefault;
-
- reflexionEdgesVisible = false;
- reflexionEdgesWidth = reflexionEdgeWidthDefault;
-
- architectureNodesVisible = true;
- implementationNodesVisible = false;
- }
-
- ///
- /// Assigns .
- ///
- private void Awake()
- {
- if (!gameObject.TryGetComponent(out CodeCity))
- {
- Debug.LogError($"Game object {name} does not have a SEECity component.\n");
- enabled = false;
- }
- else
- {
- UpdateCity();
- }
- }
-
- // --------------------------------------------
- // Update
- // --------------------------------------------
-
- private void Update()
- {
- if (Input.GetKeyDown(KeyCode.F5))
- {
- ImplementationEdgesVisible = !ImplementationEdgesVisible;
- Debug.Log("F5 pressed.\n");
- }
- if (Input.GetKeyDown(KeyCode.F6))
- {
- ArchitectureEdgesVisible = !ArchitectureEdgesVisible;
- }
- if (Input.GetKeyDown(KeyCode.F7))
- {
- ReflexionEdgesVisible = !ReflexionEdgesVisible;
- }
- if (Input.GetKeyDown(KeyCode.F11))
- {
- ArchitectureNodesVisible = !ArchitectureNodesVisible;
- }
- if (Input.GetKeyDown(KeyCode.F12))
- {
- ImplementationNodesVisible = !ImplementationNodesVisible;
- }
- }
-
- ///
- /// Sets the edge references of all edges in
- /// and colors the nodes.
- ///
- public void UpdateCity()
- {
- if (CodeCity != null)
- {
- CodeCity.SetNodeEdgeRefs();
- GameObject root = GetCityRootNode();
- if (root != null)
- {
- Debug.LogFormat("Root of {0} is {1}\n", CodeCity.name, root.name);
- SetAllNodes(root);
- SetAllEdges();
- }
- }
- else
- {
- Debug.LogErrorFormat("Code city is null in {0}.\n", name);
- }
- }
-
- ///
- /// Sets all attributes of all nodes.
- ///
- /// root node of the code city
- private void SetAllNodes(GameObject root)
- {
- ColorNodes(root);
- SetNodeVisibility(ArchitectureNodes(), architectureNodesVisible);
- SetNodeVisibility(ImplementationNodes(), implementationNodesVisible);
- }
-
- ///
- /// Sets all attributes of all edges.
- ///
- private void SetAllEdges()
- {
- SetArchitectureEdges();
- SetImplementationEdges();
- SetReflexionEdges();
- }
-
- ///
- /// Returns the root node of .
- ///
- /// root node of
- private GameObject GetCityRootNode()
- {
- return SceneQueries.GetCityRootNode(CodeCity.gameObject);
- }
-
- ///
- /// Colors architecture node with increasingly darker colors starting from white
- /// and implementation nodes with increasingly darker colors starting from yellow.
- /// The actual color used gets darker from nesting level to nesting level.
- /// Implementation leaf nodes keep their original color, however.
- ///
- /// the root of the node tree to be colored
- private void ColorNodes(GameObject root)
- {
- ColorNodes(root, architectureNode: false, Color.yellow);
- ColorNodes(root, architectureNode: true, Color.white);
- }
-
- ///
- /// Colors all nodes in the node tree rooted by using
- /// the given if and only if:
- /// (1) if is true, the nodes are architecture nodes
- /// or
- /// (2) if is false, the nodes are implementation nodes.
- /// The color is increasingly darkened from level to level, that is, the deeper a node
- /// in the node tree, the darker its color originating from the initial given .
- ///
- /// Note: The color of implementation leaf nodes is never changed.
- ///
- /// root of the node tree to be colored
- /// whether architecture nodes should be colored
- /// the new color of the nodes
- private void ColorNodes(GameObject parent, bool architectureNode, Color color)
- {
- // Is root a node at all? It may as well be an edge, for instance.
- if (parent.CompareTag(Tags.Node))
- {
- if (parent.TryGetComponent(out NodeRef nodeRef) && nodeRef.Value != null)
- {
- bool isArchitectureNode = IsArchitectureNode(parent);
- Color childColor = color;
-
- if (!isArchitectureNode && GetGraphNode(parent).IsLeaf())
- {
- // We are dealing with an implementation node that is a leaf.
- // We will not change the color of implementation nodes that are leaves;
- // neither do we need to traverse any children because there are none.
- }
- else
- {
- if ((architectureNode && isArchitectureNode) || (!architectureNode && !isArchitectureNode))
- {
- parent.SetColor(color);
- childColor = Darker(color, 0.35f);
- }
- foreach (Transform child in parent.transform)
- {
- ColorNodes(child.gameObject, architectureNode, childColor);
- }
- }
- }
- else
- {
- Debug.LogErrorFormat("Game object {0} has no valid node reference.\n", parent.name);
- }
- }
- }
-
- //-------------------
- // Edges in CodeCity
- //-------------------
-
- ///
- /// Returns all edges in the subtree rooted by .
- ///
- /// all edges in the subtree rooted by
- private List GetAllEdges()
- {
- List edges = new List();
- GameObject root = GetCityRootNode();
- AddAllEdges(root, edges);
- return edges;
- }
-
- ///
- /// Adds all edges in the subtree rooted by to .
- ///
- /// root of the subtree to be traversed
- /// where to add the found edges
- private void AddAllEdges(GameObject root, List edges)
- {
- foreach (Transform child in root.transform)
- {
- GameObject childGO = child.gameObject;
- if (childGO.CompareTag(Tags.Edge))
- {
- if (childGO.TryGetComponent(out EdgeRef edgeRef) && edgeRef.Value != null)
- {
- edges.Add(childGO);
- }
- else
- {
- Debug.LogErrorFormat("Edge {0} has no valid edge reference.\n", childGO.name);
- }
- }
- else if (childGO.CompareTag(Tags.Node))
- {
- AddAllEdges(childGO, edges);
- }
- }
- }
-
- ///
- /// Returns the graph edge represented by if there is any.
- /// Returns null if does not have a valid graph edge.
- ///
- /// game object representing an edge
- /// graph edge represented or null
- private static Edge GetGraphEdge(GameObject gameEdge)
- {
- if (gameEdge.TryGetComponent(out EdgeRef edgeRef))
- {
- return edgeRef.Value;
- }
- else
- {
- Debug.LogError($"Edge {gameEdge.name} has no valid edge reference.\n");
- return null;
- }
- }
-
- //------------------
- // Nodes in CodeCity
- //------------------
-
- ///
- /// Returns all nodes in the subtree rooted by .
- ///
- /// all nodes in the subtree rooted by
- private List GetAllNodes()
- {
- GameObject root = GetCityRootNode();
- List nodes = new List() { root };
- AddAllNodes(root, nodes);
- return nodes;
- }
-
- ///
- /// Adds all nodes in the subtree rooted by to .
- ///
- /// root of the subtree to be traversed
- /// where to add the found nodes
- private void AddAllNodes(GameObject root, List nodes)
- {
- foreach (Transform child in root.transform)
- {
- GameObject childGO = child.gameObject;
- if (childGO.CompareTag(Tags.Node))
- {
- if (childGO.TryGetComponent(out NodeRef nodeRef) && nodeRef.Value != null)
- {
- nodes.Add(childGO);
- }
- else
- {
- Debug.LogError($"Node {childGO.name} has no valid node reference.\n");
- }
- }
- AddAllNodes(childGO, nodes);
- }
- }
-
- ///
- /// Returns the graph node represented by if there is any.
- /// Returns null if does not have a valid graph node.
- ///
- /// game object representing a node
- /// graph node represented or null
- private static Node GetGraphNode(GameObject gameNode)
- {
- if (gameNode.TryGetComponent(out NodeRef nodeRef))
- {
- return nodeRef.Value;
- }
- else
- {
- Debug.LogErrorFormat("Node {0} has no valid node reference.\n", gameNode.name);
- return null;
- }
- }
-
- //------------------------------------
- // Implementation edge type properties
- //------------------------------------
-
- private bool implementationEdgesVisible = false;
- ///
- /// Whether implementation edges are visible.
- ///
- public bool ImplementationEdgesVisible
- {
- get => implementationEdgesVisible;
- set
- {
- if (implementationEdgesVisible != value)
- {
- implementationEdgesVisible = value;
- SetEdgeVisiblity(ImplementationEdgeTypes, implementationEdgesVisible);
- }
- }
- }
-
- private Color implementationEdgesStartColor = Lighter(implementationEdgesColorDefault);
- ///
- /// Start color of implementation dependencies.
- ///
- public Color ImplementationEdgesStartColor
- {
- get => implementationEdgesStartColor;
- set
- {
- if (implementationEdgesStartColor != value)
- {
- implementationEdgesStartColor = value;
- SetImplementationEdges();
- }
- }
- }
-
- private Color implementationEdgesEndColor = implementationEdgesColorDefault;
- ///
- /// End color of implementation dependencies.
- ///
- public Color ImplementationEdgesEndColor
- {
- get => implementationEdgesEndColor;
- set
- {
- if (implementationEdgesEndColor != value)
- {
- implementationEdgesEndColor = value;
- SetImplementationEdges();
- }
- }
- }
-
- private float implementationEdgesWidth = implementationEdgeWidthDefault;
- ///
- /// The width of implementation dependencies.
- ///
- public float ImplementationEdgesWidth
- {
- get => implementationEdgesWidth;
- set
- {
- if (implementationEdgesWidth != value)
- {
- implementationEdgesWidth = value;
- SetImplementationEdges();
- }
- }
- }
-
- ///
- /// Sets all attributes of implementation edges.
- ///
- private void SetImplementationEdges()
- {
- SetLine(ImplementationEdgeTypes, implementationEdgesStartColor, implementationEdgesEndColor, implementationEdgesWidth);
- SetEdgeVisiblity(ImplementationEdgeTypes, implementationEdgesVisible);
- }
-
- //------------------------------------
- // Reflexion edge type properties
- //------------------------------------
-
- private bool reflexionEdgesVisible = false;
- ///
- /// Whether reflexion edges are visible.
- ///
- public bool ReflexionEdgesVisible
- {
- get => reflexionEdgesVisible;
- set
- {
- if (reflexionEdgesVisible != value)
- {
- reflexionEdgesVisible = value;
- SetEdgeVisiblity(ReflexionEdgeTypes, reflexionEdgesVisible);
- }
- }
- }
-
- private float reflexionEdgesWidth = reflexionEdgeWidthDefault;
- ///
- /// The width of reflexion edges.
- ///
- public float ReflexionEdgesWidth
- {
- get => reflexionEdgesWidth;
- set
- {
- if (reflexionEdgesWidth != value)
- {
- reflexionEdgesWidth = value;
- SetReflexionEdges();
- }
- }
- }
-
- ///
- /// Sets start and end color and width for the lines of all reflexion edges.
- /// Absences will be colored yellow, convergences will be colored green, and
- /// divergences will be colored red. Sets the visibility of the reflexion edges.
- ///
- private void SetReflexionEdges()
- {
- SetLine(new HashSet() { "Absence" }, Color.yellow, Darker(Color.yellow), reflexionEdgesWidth);
- SetLine(new HashSet() { "Convergence" }, Color.green, Darker(Color.green), reflexionEdgesWidth);
- SetLine(new HashSet() { "Divergence" }, Color.red, Darker(Color.red), reflexionEdgesWidth);
- SetEdgeVisiblity(ReflexionEdgeTypes, reflexionEdgesVisible);
- }
-
- //------------------------------------
- // Architecture edge type properties
- //------------------------------------
-
- private bool architectureEdgesVisible = false;
- ///
- /// Whether architecture dependencies are visible.
- ///
- public bool ArchitectureEdgesVisible
- {
- get => architectureEdgesVisible;
- set
- {
- if (architectureEdgesVisible != value)
- {
- architectureEdgesVisible = value;
- SetEdgeVisiblity(ArchitectureEdgeTypes, architectureEdgesVisible);
- }
- }
- }
-
- private Color architectureEdgesStartColor = Lighter(Color.blue);
- ///
- /// Start color of architecture dependencies.
- ///
- public Color ArchitectureEdgesStartColor
- {
- get => architectureEdgesStartColor;
- set
- {
- if (architectureEdgesStartColor != value)
- {
- architectureEdgesStartColor = value;
- SetArchitectureEdges();
- }
- }
- }
-
- private Color architectureEdgesEndColor = Color.blue;
- ///
- /// End color of architecture dependencies.
- ///
- public Color ArchitectureEdgesEndColor
- {
- get => architectureEdgesEndColor;
- set
- {
- if (architectureEdgesEndColor != value)
- {
- architectureEdgesEndColor = value;
- SetArchitectureEdges();
- }
- }
- }
-
- private float architectureEdgesWidth = architectureEdgeWidthDefault;
- ///
- /// The width of architecture dependencies.
- ///
- public float ArchitectureEdgesWidth
- {
- get => architectureEdgesWidth;
- set
- {
- if (architectureEdgesWidth != value)
- {
- architectureEdgesWidth = value;
- SetArchitectureEdges();
- }
- }
- }
-
- ///
- /// Sets all attributes of all architecture edges.
- ///
- private void SetArchitectureEdges()
- {
- SetLine(ArchitectureEdgeTypes, architectureEdgesStartColor, architectureEdgesEndColor, architectureEdgesWidth);
- SetEdgeVisiblity(ArchitectureEdgeTypes, architectureEdgesVisible);
- }
-
- ///
- /// Set the visibility of all edges in the that have
- /// any of the given to .
- ///
- /// relevant edge types for setting the visibility
- /// new visibility
- private void SetEdgeVisiblity(HashSet edgeTypes, bool show)
- {
- foreach (GameObject go in GetAllEdges())
- {
- if (edgeTypes == AllEdgeTypes || edgeTypes.Contains(GetGraphEdge(go).Type))
- {
- go.SetVisibility(show);
- }
- }
- }
-
- ///
- /// For every edge in having a type included in the given
- /// , the given line attributes will be set.
- ///
- /// relevant edge types
- /// starting color of the line
- /// ending color of the line
- /// width of the line
- private void SetLine(HashSet edgeTypes, Color startColor, Color endColor, float width)
- {
- foreach (GameObject go in GetAllEdges())
- {
- if (edgeTypes == AllEdgeTypes || edgeTypes.Contains(GetGraphEdge(go).Type))
- {
- LineRenderer renderer = go.GetComponent();
- if (renderer != null)
- {
- renderer.startColor = startColor;
- renderer.endColor = endColor;
- renderer.startWidth = width;
- renderer.endWidth = width;
- }
- }
- }
- }
-
- //------------------------------------
- // Architecture node type properties
- //------------------------------------
-
- private bool architectureNodesVisible = true;
- ///
- /// Whether architecture nodes are visible.
- ///
- public bool ArchitectureNodesVisible
- {
- get => architectureNodesVisible;
- set
- {
- if (architectureNodesVisible != value)
- {
- architectureNodesVisible = value;
- SetNodeVisibility(ArchitectureNodes(), architectureNodesVisible);
- }
- }
- }
-
- private bool implementationNodesVisible = false;
- ///
- /// Whether implementation nodes are visible.
- ///
- public bool ImplementationNodesVisible
- {
- get => implementationNodesVisible;
- set
- {
- if (implementationNodesVisible != value)
- {
- implementationNodesVisible = value;
- SetNodeVisibility(ImplementationNodes(), implementationNodesVisible);
- }
- }
- }
-
- ///
- /// Returns all architecture nodes in .
- ///
- /// all architecture nodes
- private List ArchitectureNodes()
- {
- List result = new List();
- foreach (GameObject go in GetAllNodes())
- {
- if (IsArchitectureNode(go))
- {
- result.Add(go);
- }
- }
- return result;
- }
-
- ///
- /// Returns true if is an architecture node (has
- /// type Cluster).
- ///
- /// game object representing a node
- /// true if architecture node
- private static bool IsArchitectureNode(GameObject go)
- {
- return GetGraphNode(go).Type == "Cluster";
- }
-
- ///
- /// Returns all implementation nodes in the .
- ///
- /// all implementation nodes
- private List ImplementationNodes()
- {
- List result = new List();
- foreach (GameObject go in GetAllNodes())
- {
- if (!IsArchitectureNode(go))
- {
- result.Add(go);
- }
- }
- return result;
- }
-
- ///
- /// Sets the visibility of all to .
- ///
- /// game objects whose visibility is to be set
- /// the new visibility
- private static void SetNodeVisibility(ICollection nodes, bool show)
- {
- foreach (GameObject go in nodes)
- {
- go.SetVisibility(show, includingChildren: false);
- }
- }
-
- ///
- /// Returns given lightened by 50%.
- ///
- /// base color to be lightened
- /// given lightened by 50%
- private static Color Lighter(Color color)
- {
- return Color.Lerp(color, Color.white, 0.5f); // To lighten by 50 %
- }
-
- ///
- /// Returns given darkened by .
- ///
- /// Precondition: 0 <= <= 1
- ///
- /// base color to be darkened
- /// degree by which to darker the given
- /// given darkened by
- private static Color Darker(Color color, float degree = 0.5f)
- {
- return Color.Lerp(color, Color.black, degree);
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/SEE/Game/EdgeRenderer.cs b/Assets/SEE/Game/EdgeRenderer.cs
index 44f41e69b6..9eb8dcfe2f 100644
--- a/Assets/SEE/Game/EdgeRenderer.cs
+++ b/Assets/SEE/Game/EdgeRenderer.cs
@@ -155,7 +155,7 @@ private GameObject DrawEdge(Edge edge, GameObject from, GameObject to, bool addT
Assert.IsNotNull(toLayoutNode, $"Target node {edge.Target.ID} does not have a layout node.\n");
// The single layout edge between source and target. We want the layout only for this edge.
ICollection> layoutEdges = new List>
- { new LayoutGraphEdge(fromLayoutNode, toLayoutNode, edge) };
+ { new(fromLayoutNode, toLayoutNode, edge) };
// Calculate the edge layout (for the single edge only).
@@ -216,6 +216,35 @@ public GameObject DrawEdge(GameObject source, GameObject target, string edgeType
return DrawEdge(edge, source, target, true);
}
+ ///
+ /// Draws and returns a new game edge
+ /// based on the current settings.
+ ///
+ /// Note: The default edge layout will be used if no edge layout,
+ /// i.e., , was chosen in the settings.
+ ///
+ /// Precondition: and must have a valid
+ /// node reference. The corresponding graph nodes must be in the same graph.
+ ///
+ /// the edge to be drawn
+ /// GameObject of source of the new edge
+ /// GameObject of target of the new edge
+ /// The new game object representing the given edge.
+ public GameObject DrawEdge(Edge edge, GameObject sourceNode = null, GameObject targetNode = null)
+ {
+ if (sourceNode == null)
+ {
+ sourceNode = GraphElementIDMap.Find(edge.Source.ID);
+ }
+
+ if (targetNode == null)
+ {
+ targetNode = GraphElementIDMap.Find(edge.Target.ID);
+ }
+
+ return DrawEdge(edge, sourceNode, targetNode, true);
+ }
+
///
/// Adds and all its transitive parent game objects tagged by
/// to .
@@ -393,4 +422,4 @@ private static ICollection> ConnectingEdges(ICollection
return edges;
}
}
-}
\ No newline at end of file
+}
diff --git a/Assets/SEE/Game/Evolution/EvolutionRenderer.cs b/Assets/SEE/Game/Evolution/EvolutionRenderer.cs
index df73a6f44b..2483d4c4bb 100644
--- a/Assets/SEE/Game/Evolution/EvolutionRenderer.cs
+++ b/Assets/SEE/Game/Evolution/EvolutionRenderer.cs
@@ -932,6 +932,16 @@ public GameObject DrawNode(Node node, GameObject city = null)
return Renderer.DrawNode(node, city);
}
+ ///
+ /// Placeholder to satisfy the compiler. This method is not
+ /// called anywhere as of yet, but was required in .
+ ///
+ public GameObject DrawEdge(Edge edge, GameObject source = null, GameObject target = null)
+ {
+ throw new NotImplementedException();
+ }
+
///
/// Returns an edge layout for the given .
///
diff --git a/Assets/SEE/Game/GameNodeScaler.cs b/Assets/SEE/Game/GameNodeScaler.cs
deleted file mode 100644
index 6fe3e02124..0000000000
--- a/Assets/SEE/Game/GameNodeScaler.cs
+++ /dev/null
@@ -1,101 +0,0 @@
-using System.Collections.Generic;
-using UnityEditor;
-using UnityEngine;
-
-namespace SEE.Game
-{
- ///
- /// This GameNodeScaler allows us to scale a game node without modifying the
- /// scale of its children.
- ///
- [ExecuteInEditMode]
- public class GameNodeScaler : MonoBehaviour
- {
- ///
- /// The target scale of the game object in world space co-ordinates.
- ///
- public Vector3 TargetScale;
-
- ///
- /// Sets to the current scale of the game object.
- ///
- void Start()
- {
- Init();
- }
-
- ///
- /// Sets to the current scale of the game object.
- /// Called when the component is reset in the editor.
- ///
- void Reset()
- {
- Init();
- }
-
- private void Init()
- {
- TargetScale = transform.lossyScale;
- enabled = false;
- }
-
- ///
- /// If has changed, the scale of the game object is set
- /// to (in world space). The children of the game object
- /// are not re-sized.
- ///
- void Update()
- {
- if (TargetScale != transform.lossyScale)
- {
- Debug.LogFormat("{0} original world scale = {1}; target world scale: {2}\n",
- name, transform.lossyScale.ToString("F4"), TargetScale.ToString("F4"));
- ScaleOnlyRootGameObject(gameObject, TargetScale);
-
-#if UNITY_EDITOR
- EditorUtility.SetDirty(gameObject);
- SceneView.RepaintAll();
-#endif
- TargetScale = transform.lossyScale;
- }
- }
-
- ///
- /// Resizes given to given
- /// in world space without resizing any of its children.
- ///
- /// game object to be resized
- /// the target scale in world-space co-ordinates
- private static void ScaleOnlyRootGameObject(GameObject gameObject, Vector3 targetScale)
- {
- // The children of gameObject:
- List children = new List();
- // Save the children of gameObject.
- foreach (Transform child in gameObject.transform)
- {
- children.Add(child);
- }
- // Unparent all children of gameObject so that they do not scale along with gameObject.
- foreach (Transform child in children)
- {
- child.parent = null;
- }
- {
- // Resize gameObject and only gameObject in world space.
- // The parent of gameObject (may be null):
- Transform parent = gameObject.transform.parent;
- // Unparent gameObject because targetScale is meant to be in world space.
- gameObject.transform.parent = null;
- // Resize gameObject.
- gameObject.transform.localScale = targetScale;
- // Re-parent gameObject.
- gameObject.transform.parent = parent;
- }
- // Re-parent all children of gameObject.
- foreach (Transform child in children)
- {
- child.parent = gameObject.transform;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/SEE/Game/IGraphRenderer.cs b/Assets/SEE/Game/IGraphRenderer.cs
index 5506c8d97f..9b3efe7b0a 100644
--- a/Assets/SEE/Game/IGraphRenderer.cs
+++ b/Assets/SEE/Game/IGraphRenderer.cs
@@ -34,6 +34,22 @@ public interface IGraphRenderer
/// are not contained in any graph or contained in different graphs
GameObject DrawEdge(GameObject source, GameObject target, string edgeType);
+ ///
+ /// Draws and returns a new game edge
+ /// based on the current settings.
+ ///
+ /// Note: The default edge layout will be used if no edge layout,
+ /// i.e., , was chosen in the settings.
+ ///
+ /// Precondition: and must either have a valid
+ /// node reference or be null. The corresponding graph nodes must be in the same graph.
+ ///
+ /// the edge to be drawn
+ /// GameObject of source of the new edge
+ /// GameObject of target of the new edge
+ /// The new game object representing the given edge.
+ GameObject DrawEdge(Edge edge, GameObject source = null, GameObject target = null);
+
///
/// Returns an edge layout for the given .
///
@@ -61,4 +77,4 @@ public interface IGraphRenderer
/// game object representing given
GameObject DrawNode(Node node, GameObject city = null);
}
-}
\ No newline at end of file
+}
diff --git a/Assets/SEE/Game/InteractionDecorator.cs b/Assets/SEE/Game/InteractionDecorator.cs
index 67419b67c6..2ee3d90228 100644
--- a/Assets/SEE/Game/InteractionDecorator.cs
+++ b/Assets/SEE/Game/InteractionDecorator.cs
@@ -40,7 +40,6 @@ public static void PrepareForInteraction(GameObject gameObject)
gameObject.AddComponentIfNecessary();
if (gameObject.HasNodeRef())
{
- gameObject.AddComponentIfNecessary();
gameObject.AddComponentIfNecessary();
gameObject.AddComponentIfNecessary();
gameObject.AddComponentIfNecessary();
diff --git a/Assets/SEE/Game/SceneManipulation.meta b/Assets/SEE/Game/SceneManipulation.meta
new file mode 100644
index 0000000000..29ac170949
--- /dev/null
+++ b/Assets/SEE/Game/SceneManipulation.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 2f2874a20ebd0a5428e97d6c6f3494d8
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/SEE/Game/SceneManipulation/AcceptDivergence.cs b/Assets/SEE/Game/SceneManipulation/AcceptDivergence.cs
new file mode 100644
index 0000000000..34aec28767
--- /dev/null
+++ b/Assets/SEE/Game/SceneManipulation/AcceptDivergence.cs
@@ -0,0 +1,83 @@
+using SEE.DataModel.DG;
+using SEE.GO;
+using SEE.Tools.ReflexionAnalysis;
+using UnityEngine;
+
+namespace SEE.Game.SceneManipulation
+{
+ ///
+ /// Adds an edge to a reflexion graph allowing a currently divergent implementation
+ /// dependency.
+ ///
+ public static class AcceptDivergence
+ {
+ ///
+ /// Adds a new edge of given from
+ /// to to the graph is contained in
+ /// via . Then the edge is
+ /// drawn.
+ ///
+ /// Preconditions: and both have
+ /// valid s that are in the same graph and this graph is a
+ /// . Given must be a unique
+ /// edge ID.
+ ///
+ /// the game object holding the source of the edge
+ /// the game object holding the target of the edge
+ /// the type of the edge
+ /// the unique ID the edge should have
+ /// the edge that was created and added to the graph
+ public static Edge Accept(GameObject from, GameObject to, string edgeType, string edgeId)
+ {
+ if (from.TryGetNode(out Node fromNode))
+ {
+ if (to.TryGetNode(out Node toNode))
+ {
+ return Accept(fromNode, toNode, edgeType, edgeId);
+ }
+ else
+ {
+ throw new System.Exception($"Game node {toNode.ID} has not graph node attached.\n");
+ }
+ }
+ else
+ {
+ throw new System.Exception($"Game node {fromNode.ID} has not graph node attached.\n");
+ }
+ }
+
+ ///
+ /// Adds a new edge of given from
+ /// to to the graph is contained in
+ /// via . Then the edge is
+ /// drawn.
+ ///
+ /// Preconditions: and are in the
+ /// same graph and this graph is a . If
+ /// is given, it must be a unique edge ID.
+ ///
+ /// the source of the edge
+ /// the target of the edge
+ /// the type of the edge
+ /// the unique ID the edge should have; if null or empty
+ /// a unique ID will be created
+ /// the edge that was created and added to the graph
+ public static Edge Accept(Node from, Node to, string edgeType, string edgeId = null)
+ {
+ Edge result = new(from, to, edgeType);
+
+ if (!string.IsNullOrEmpty(edgeId))
+ {
+ result.ID = edgeId;
+ }
+
+ if (from.ItsGraph is ReflexionGraph graph)
+ {
+ graph.AddToArchitecture(result);
+ }
+
+ GameEdgeAdder.Draw(result);
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/Editor/ArchitectureInteractionEditor.cs.meta b/Assets/SEE/Game/SceneManipulation/AcceptDivergence.cs.meta
similarity index 83%
rename from Assets/Editor/ArchitectureInteractionEditor.cs.meta
rename to Assets/SEE/Game/SceneManipulation/AcceptDivergence.cs.meta
index 4119343cf8..e442d446cf 100644
--- a/Assets/Editor/ArchitectureInteractionEditor.cs.meta
+++ b/Assets/SEE/Game/SceneManipulation/AcceptDivergence.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 3ef6249495394044fbb78b81be55017b
+guid: e48734750aff8b2438f688d5e62c11c8
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Assets/SEE/Game/GameEdgeAdder.cs b/Assets/SEE/Game/SceneManipulation/GameEdgeAdder.cs
similarity index 79%
rename from Assets/SEE/Game/GameEdgeAdder.cs
rename to Assets/SEE/Game/SceneManipulation/GameEdgeAdder.cs
index 2b75968745..06614980ff 100644
--- a/Assets/SEE/Game/GameEdgeAdder.cs
+++ b/Assets/SEE/Game/SceneManipulation/GameEdgeAdder.cs
@@ -4,10 +4,10 @@
using SEE.GO;
using UnityEngine;
-namespace SEE.Game
+namespace SEE.Game.SceneManipulation
{
///
- /// Creates new game objects representing graph edges or deleting these again,
+ /// Creates new game objects representing graph edges or deletes these again,
/// respectively.
///
public class GameEdgeAdder
@@ -54,6 +54,29 @@ public static GameObject Add(GameObject source, GameObject target, string edgeTy
return result;
}
+ ///
+ /// Simply (re)draws an edge.
+ ///
+ /// the edge that should be (re)drawn
+ /// the GameObject of the drawn edge
+ public static GameObject Draw(Edge edge)
+ {
+ GameObject source = GraphElementIDMap.Find(edge.Source.ID);
+ Transform cityObject = SceneQueries.GetCodeCity(source.transform);
+
+ if (!cityObject)
+ {
+ throw new Exception($"The code city for the new edge {edge.ToShortString()} cannot be determined.\n");
+ }
+
+ if (!cityObject.TryGetComponent(out AbstractSEECity city))
+ {
+ throw new Exception($"Could not determine the code city for the new edge {edge.ToShortString()}.\n");
+ }
+
+ return city.Renderer.DrawEdge(edge, source: source);
+ }
+
///
/// Inverse operation of .
/// Removes the given from the scene and its associated
diff --git a/Assets/SEE/Game/GameEdgeAdder.cs.meta b/Assets/SEE/Game/SceneManipulation/GameEdgeAdder.cs.meta
similarity index 100%
rename from Assets/SEE/Game/GameEdgeAdder.cs.meta
rename to Assets/SEE/Game/SceneManipulation/GameEdgeAdder.cs.meta
diff --git a/Assets/SEE/Game/GameElementDeleter.cs b/Assets/SEE/Game/SceneManipulation/GameElementDeleter.cs
similarity index 99%
rename from Assets/SEE/Game/GameElementDeleter.cs
rename to Assets/SEE/Game/SceneManipulation/GameElementDeleter.cs
index c44bcad5ff..5f7aa824c7 100644
--- a/Assets/SEE/Game/GameElementDeleter.cs
+++ b/Assets/SEE/Game/SceneManipulation/GameElementDeleter.cs
@@ -6,7 +6,7 @@
using SEE.Tools.ReflexionAnalysis;
using UnityEngine;
-namespace SEE.Game
+namespace SEE.Game.SceneManipulation
{
///
/// Allows to delete nodes and edges.
@@ -106,7 +106,7 @@ private static (GraphElementsMemento, ISet) DeleteEdge(GameObject ga
{
// The edge memento must be created before the edge is removed;
// otherwise ItsGraph would be null.
- EdgeMemento edgeMemento = new EdgeMemento(edgeRef.Value);
+ EdgeMemento edgeMemento = new(edgeRef.Value);
edgeRef.Value.ItsGraph.RemoveEdge(edgeRef.Value);
GameObjectFader.FadingOut(gameEdge, SetInactive);
return (edgeMemento, new HashSet() { gameEdge });
diff --git a/Assets/SEE/Game/GameElementDeleter.cs.meta b/Assets/SEE/Game/SceneManipulation/GameElementDeleter.cs.meta
similarity index 100%
rename from Assets/SEE/Game/GameElementDeleter.cs.meta
rename to Assets/SEE/Game/SceneManipulation/GameElementDeleter.cs.meta
diff --git a/Assets/SEE/Game/GameNodeAdder.cs b/Assets/SEE/Game/SceneManipulation/GameNodeAdder.cs
similarity index 99%
rename from Assets/SEE/Game/GameNodeAdder.cs
rename to Assets/SEE/Game/SceneManipulation/GameNodeAdder.cs
index 9dd226312f..d4d771aa4b 100644
--- a/Assets/SEE/Game/GameNodeAdder.cs
+++ b/Assets/SEE/Game/SceneManipulation/GameNodeAdder.cs
@@ -4,7 +4,7 @@
using SEE.GO;
using UnityEngine;
-namespace SEE.Game
+namespace SEE.Game.SceneManipulation
{
///
/// Creates new game objects representing graph nodes or deleting these again,
diff --git a/Assets/SEE/Game/GameNodeAdder.cs.meta b/Assets/SEE/Game/SceneManipulation/GameNodeAdder.cs.meta
similarity index 100%
rename from Assets/SEE/Game/GameNodeAdder.cs.meta
rename to Assets/SEE/Game/SceneManipulation/GameNodeAdder.cs.meta
diff --git a/Assets/SEE/Game/GameNodeMover.cs b/Assets/SEE/Game/SceneManipulation/GameNodeMover.cs
similarity index 99%
rename from Assets/SEE/Game/GameNodeMover.cs
rename to Assets/SEE/Game/SceneManipulation/GameNodeMover.cs
index 55cc9b706a..51a7134225 100644
--- a/Assets/SEE/Game/GameNodeMover.cs
+++ b/Assets/SEE/Game/SceneManipulation/GameNodeMover.cs
@@ -3,7 +3,7 @@
using UnityEngine;
using UnityEngine.Assertions;
-namespace SEE.Game
+namespace SEE.Game.SceneManipulation
{
///
/// Allows to move game nodes (game objects representing a graph node).
diff --git a/Assets/SEE/Game/GameNodeMover.cs.meta b/Assets/SEE/Game/SceneManipulation/GameNodeMover.cs.meta
similarity index 100%
rename from Assets/SEE/Game/GameNodeMover.cs.meta
rename to Assets/SEE/Game/SceneManipulation/GameNodeMover.cs.meta
diff --git a/Assets/SEE/Game/GameObjectFader.cs b/Assets/SEE/Game/SceneManipulation/GameObjectFader.cs
similarity index 99%
rename from Assets/SEE/Game/GameObjectFader.cs
rename to Assets/SEE/Game/SceneManipulation/GameObjectFader.cs
index 5645babf91..2788aa598f 100644
--- a/Assets/SEE/Game/GameObjectFader.cs
+++ b/Assets/SEE/Game/SceneManipulation/GameObjectFader.cs
@@ -5,7 +5,7 @@
using SEE.Utils;
using UnityEngine;
-namespace SEE.Game
+namespace SEE.Game.SceneManipulation
{
///
/// Provides fading in and out for game objects. There are static as well as instance methods
diff --git a/Assets/SEE/Game/GameObjectFader.cs.meta b/Assets/SEE/Game/SceneManipulation/GameObjectFader.cs.meta
similarity index 100%
rename from Assets/SEE/Game/GameObjectFader.cs.meta
rename to Assets/SEE/Game/SceneManipulation/GameObjectFader.cs.meta
diff --git a/Assets/SEE/Game/GameObjectFlasher.cs b/Assets/SEE/Game/SceneManipulation/GameObjectFlasher.cs
similarity index 98%
rename from Assets/SEE/Game/GameObjectFlasher.cs
rename to Assets/SEE/Game/SceneManipulation/GameObjectFlasher.cs
index ad7615121b..ca53ce9c17 100644
--- a/Assets/SEE/Game/GameObjectFlasher.cs
+++ b/Assets/SEE/Game/SceneManipulation/GameObjectFlasher.cs
@@ -2,7 +2,7 @@
using DG.Tweening;
using SEE.Utils;
-namespace SEE.Game
+namespace SEE.Game.SceneManipulation
{
///
/// Flashes a game object, that is, animates its color pulsating from its
diff --git a/Assets/SEE/Game/GameObjectFlasher.cs.meta b/Assets/SEE/Game/SceneManipulation/GameObjectFlasher.cs.meta
similarity index 100%
rename from Assets/SEE/Game/GameObjectFlasher.cs.meta
rename to Assets/SEE/Game/SceneManipulation/GameObjectFlasher.cs.meta
diff --git a/Assets/SEE/Game/SceneManipulation/SceneManipulation.cs b/Assets/SEE/Game/SceneManipulation/SceneManipulation.cs
new file mode 100644
index 0000000000..7442f512f1
--- /dev/null
+++ b/Assets/SEE/Game/SceneManipulation/SceneManipulation.cs
@@ -0,0 +1,10 @@
+///
+/// This namespace contains (typically static) classes that manipulate
+/// game objects in the scene representing nodes or edges. They will
+/// be shared among our Actions and their corresponding NetActions.
+/// The intention here is to avoid redundancy among Actions and
+/// NetActions as both need to change the scene the same way.
+///
+namespace SEE.Game.SceneManipulation
+{
+}
\ No newline at end of file
diff --git a/Assets/SEE/Game/ArchitectureInteraction.cs.meta b/Assets/SEE/Game/SceneManipulation/SceneManipulation.cs.meta
similarity index 83%
rename from Assets/SEE/Game/ArchitectureInteraction.cs.meta
rename to Assets/SEE/Game/SceneManipulation/SceneManipulation.cs.meta
index 02d74be976..1df626b538 100644
--- a/Assets/SEE/Game/ArchitectureInteraction.cs.meta
+++ b/Assets/SEE/Game/SceneManipulation/SceneManipulation.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 4f25e472fae0c304e994d615ed8259db
+guid: 2d32acb5594a0914b9461bd09533736f
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Assets/SEE/Net/Actions/AcceptDivergenceNetAction.cs b/Assets/SEE/Net/Actions/AcceptDivergenceNetAction.cs
new file mode 100644
index 0000000000..e4e26df2dd
--- /dev/null
+++ b/Assets/SEE/Net/Actions/AcceptDivergenceNetAction.cs
@@ -0,0 +1,77 @@
+using SEE.DataModel.DG;
+using UnityEngine;
+using SEE.GO;
+using SEE.Tools.ReflexionAnalysis;
+using SEE.Game.SceneManipulation;
+
+namespace SEE.Net.Actions
+{
+ ///
+ /// This class is responsible for adding a specific edge via
+ /// network from one client to all others and to the server, in
+ /// order to solve a divergence.
+ ///
+ public class AcceptDivergenceNetAction : AbstractNetAction
+ {
+ ///
+ /// The ID of the Node's GameObject from which the edge should be
+ /// drawn (source node).
+ ///
+ public string FromId;
+
+ ///
+ /// The ID of the Node's GameObject to which the edge should be drawn
+ /// (target node).
+ ///
+ public string ToId;
+
+ ///
+ /// The ID of the server's edge to ensure they match
+ /// between server and clients.
+ ///
+ public string EdgeId;
+
+ ///
+ /// The type of the edge that should be created in order to
+ /// solve the divergence.
+ ///
+ public string Type;
+
+ ///
+ /// Constructor.
+ ///
+ /// ID of the source node of the edge
+ /// ID for target node of the edge
+ /// ID of the edge to be propagated to the clients
+ /// the type of the created edge
+ public AcceptDivergenceNetAction(string fromId, string toId, string edgeId, string type)
+ : base()
+ {
+ FromId = fromId;
+ ToId = toId;
+ EdgeId = edgeId;
+ Type = type;
+ }
+
+ ///
+ /// Things to execute on the server (none for this
+ /// class). Necessary because it is abstract in the
+ /// superclass.
+ ///
+ protected override void ExecuteOnServer()
+ {
+ // Intentionally left blank.
+ }
+
+ ///
+ /// Creates a new GameObject on each client.
+ ///
+ protected override void ExecuteOnClient()
+ {
+ if (!IsRequester())
+ {
+ AcceptDivergence.Accept(Find(FromId), Find(ToId), Type, EdgeId);
+ }
+ }
+ }
+}
diff --git a/Assets/SEE/Net/Actions/AcceptDivergenceNetAction.cs.meta b/Assets/SEE/Net/Actions/AcceptDivergenceNetAction.cs.meta
new file mode 100644
index 0000000000..e3ea553c32
--- /dev/null
+++ b/Assets/SEE/Net/Actions/AcceptDivergenceNetAction.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 724ad0b3aa74ecf5f9afd1bde58e9762
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/SEE/Net/Actions/AddEdgeNetAction.cs b/Assets/SEE/Net/Actions/AddEdgeNetAction.cs
index 303993f920..1cfa434925 100644
--- a/Assets/SEE/Net/Actions/AddEdgeNetAction.cs
+++ b/Assets/SEE/Net/Actions/AddEdgeNetAction.cs
@@ -1,5 +1,5 @@
using SEE.Game;
-using UnityEngine;
+using SEE.Game.SceneManipulation;
namespace SEE.Net.Actions
{
@@ -52,23 +52,7 @@ protected override void ExecuteOnClient()
{
if (!IsRequester())
{
- GameObject fromGO = GraphElementIDMap.Find(FromId);
- if (fromGO)
- {
- GameObject toGO = GraphElementIDMap.Find(ToId);
- if (toGO)
- {
- GameEdgeAdder.Add(fromGO, toGO, EdgeType);
- }
- else
- {
- Debug.LogError($"There is no game node named {ToId} for the target of new edge {EdgeType}.\n");
- }
- }
- else
- {
- Debug.LogError($"There is no game node named {FromId} for the source of new edge {EdgeType}.\n");
- }
+ GameEdgeAdder.Add(Find(FromId), GraphElementIDMap.Find(ToId), EdgeType);
}
}
}
diff --git a/Assets/SEE/Net/Actions/AddNodeNetAction.cs b/Assets/SEE/Net/Actions/AddNodeNetAction.cs
index 8a12c1dda2..53a3421cbc 100644
--- a/Assets/SEE/Net/Actions/AddNodeNetAction.cs
+++ b/Assets/SEE/Net/Actions/AddNodeNetAction.cs
@@ -1,4 +1,4 @@
-using SEE.Game;
+using SEE.Game.SceneManipulation;
using UnityEngine;
namespace SEE.Net.Actions
diff --git a/Assets/SEE/Net/Actions/DeleteNetAction.cs b/Assets/SEE/Net/Actions/DeleteNetAction.cs
index 1e39122978..e32324a655 100644
--- a/Assets/SEE/Net/Actions/DeleteNetAction.cs
+++ b/Assets/SEE/Net/Actions/DeleteNetAction.cs
@@ -1,4 +1,5 @@
using SEE.Game;
+using SEE.Game.SceneManipulation;
using UnityEngine;
namespace SEE.Net.Actions
diff --git a/Assets/SEE/Net/Actions/MoveNetAction.cs b/Assets/SEE/Net/Actions/MoveNetAction.cs
index a97db27055..8362336813 100644
--- a/Assets/SEE/Net/Actions/MoveNetAction.cs
+++ b/Assets/SEE/Net/Actions/MoveNetAction.cs
@@ -1,4 +1,5 @@
using SEE.Game;
+using SEE.Game.SceneManipulation;
using UnityEngine;
namespace SEE.Net.Actions
diff --git a/Assets/SEE/Net/Actions/PutOnAndFitNetAction.cs b/Assets/SEE/Net/Actions/PutOnAndFitNetAction.cs
index 14744bee5f..b011efebfb 100644
--- a/Assets/SEE/Net/Actions/PutOnAndFitNetAction.cs
+++ b/Assets/SEE/Net/Actions/PutOnAndFitNetAction.cs
@@ -1,4 +1,5 @@
using SEE.Game;
+using SEE.Game.SceneManipulation;
using UnityEngine;
namespace SEE.Net.Actions
diff --git a/Assets/SEE/Net/Actions/ReviveNetAction.cs b/Assets/SEE/Net/Actions/ReviveNetAction.cs
index 5da8003146..c4ada31951 100644
--- a/Assets/SEE/Net/Actions/ReviveNetAction.cs
+++ b/Assets/SEE/Net/Actions/ReviveNetAction.cs
@@ -1,4 +1,5 @@
using SEE.Game;
+using SEE.Game.SceneManipulation;
using SEE.Utils;
using System.Collections.Generic;
using UnityEngine;
diff --git a/Assets/SEE/Net/Actions/SetParentNetAction.cs b/Assets/SEE/Net/Actions/SetParentNetAction.cs
index d802eb8a47..b50eb99b46 100644
--- a/Assets/SEE/Net/Actions/SetParentNetAction.cs
+++ b/Assets/SEE/Net/Actions/SetParentNetAction.cs
@@ -1,4 +1,5 @@
using SEE.Game;
+using SEE.Game.SceneManipulation;
namespace SEE.Net.Actions
{
diff --git a/Assets/SEE/Net/Actions/VersionNetAction.cs b/Assets/SEE/Net/Actions/VersionNetAction.cs
index e3a7906306..9020d5dbf2 100644
--- a/Assets/SEE/Net/Actions/VersionNetAction.cs
+++ b/Assets/SEE/Net/Actions/VersionNetAction.cs
@@ -1,5 +1,5 @@
using SEE.Game;
-using UnityEngine;
+using SEE.Game.SceneManipulation;
namespace SEE.Net.Actions
{
diff --git a/Assets/SEE/Tools/ReflexionAnalysis/Incremental.cs b/Assets/SEE/Tools/ReflexionAnalysis/Incremental.cs
index 036a5ab3ed..045157c2bb 100644
--- a/Assets/SEE/Tools/ReflexionAnalysis/Incremental.cs
+++ b/Assets/SEE/Tools/ReflexionAnalysis/Incremental.cs
@@ -21,13 +21,13 @@ public partial class ReflexionGraph
/// adjusting the reflexion analysis incrementally.
/// This will propagate and lift the new edge, thereby increasing the counter of the matching specified edge
/// if it exists.
- ///
+ ///
/// Preconditions:
///
/// - is contained in the implementation graph.
/// - is contained in the implementation graph.
///
- ///
+ ///
/// Postcondition: A new edge from to
/// is contained in the implementation graph and the reflexion data is updated;
/// all observers are informed of the change by an event.
@@ -52,10 +52,10 @@ public Edge AddToImplementation(Node from, Node to, string type)
///
/// Adds the given to the implementation graph,
/// adjusting the reflexion analysis incrementally.
- ///
+ ///
/// This will propagate and lift the new edge, thereby increasing the counter of the matching specified edge
/// if it exists.
- ///
+ ///
/// Preconditions:
///
/// - .Source is contained in the implementation graph.
@@ -67,9 +67,9 @@ public Edge AddToImplementation(Node from, Node to, string type)
/// not in the implementation graph
public void AddToImplementation(Edge edge)
{
- AssertOrThrow(ContainsNode(edge.Source) && edge.Source.IsInImplementation(),
+ AssertOrThrow(ContainsNode(edge.Source) && edge.Source.IsInImplementation(),
() => new NotInSubgraphException(Implementation, edge.Source));
- AssertOrThrow(ContainsNode(edge.Target) && edge.Target.IsInImplementation(),
+ AssertOrThrow(ContainsNode(edge.Target) && edge.Target.IsInImplementation(),
() => new NotInSubgraphException(Implementation, edge.Target));
edge.SetInImplementation();
SetState(edge, State.Undefined);
@@ -143,7 +143,7 @@ public void RemoveFromImplementation(Edge edge)
/// adjusting the reflexion analysis incrementally.
/// This edge will be considered as a specified dependency.
/// It may not be redundant.
- ///
+ ///
/// Preconditions:
///
/// - is contained in the architecture graph.
@@ -169,13 +169,14 @@ public Edge AddToArchitecture(Node from, Node to, string type)
return edge;
}
+
///
/// Adds the given to the implementation graph,
/// adjusting the reflexion analysis incrementally.
- ///
+ ///
/// This will propagate and lift the new edge, thereby increasing the counter of the matching specified edge
/// if it exists.
- ///
+ ///
/// Preconditions:
///
/// - .Source is contained in the implementation graph.
@@ -187,9 +188,9 @@ public Edge AddToArchitecture(Node from, Node to, string type)
/// not in the implementation graph
public void AddToArchitecture(Edge edge)
{
- AssertOrThrow(ContainsNode(edge.Source) && edge.Source.IsInArchitecture(),
+ AssertOrThrow(ContainsNode(edge.Source) && edge.Source.IsInArchitecture(),
() => new NotInSubgraphException(Architecture, edge.Source));
- AssertOrThrow(ContainsNode(edge.Target) && edge.Target.IsInArchitecture(),
+ AssertOrThrow(ContainsNode(edge.Target) && edge.Target.IsInArchitecture(),
() => new NotInSubgraphException(Architecture, edge.Target));
AssertNotRedundant(edge.Source, edge.Target, edge.Type);
edge.SetInArchitecture();
@@ -414,7 +415,7 @@ public void AddToArchitecture(Node node)
/// If is true, the children of
/// become root nodes. Otherwise they become children of the parent of
/// if there is a parent.
- ///
+ ///
/// Precondition: must be contained in the architecture graph.
/// Postcondition: is no longer contained in the architecture graph and the reflexion
/// data is updated; all observers are informed of the change.
@@ -460,7 +461,7 @@ public void AddToImplementation(Node node)
/// If is true, the children of
/// become root nodes. Otherwise they become children of the parent of
/// if there is a parent.
- ///
+ ///
/// Precondition: must be contained in the implementation graph.
/// Postcondition: is no longer contained in the implementation graph and the reflexion
/// data is updated; all observers are informed of the change.
@@ -548,7 +549,7 @@ public void UnparentInImplementation(Node child)
child.Reparent(null);
if (formerTarget != null && !IsExplicitlyMapped(child))
{
- // If child was implicitly mapped, this was due to parent, which means we now
+ // If child was implicitly mapped, this was due to parent, which means we now
// have to revert that effect on child and its subtree.
List subtree = MappedSubtree(child);
Unmap(subtree, formerTarget);
@@ -597,7 +598,7 @@ public void AddChildInArchitecture(Node child, Node parent)
foreach (Edge outgoing in ascendant.Outgoings)
{
// We needn't check the "supertree", as we are already iterating over ascendants, hence
- // we are setting that parameter to empty collections.
+ // we are setting that parameter to empty collections.
// Since the only change in this operation will be the additional subtree rooted by `child`,
// we only need to compare this outgoing edge by that subtree.
AssertNotRedundant(outgoing.Source, outgoing.Target, outgoing.Type,
@@ -608,7 +609,7 @@ public void AddChildInArchitecture(Node child, Node parent)
foreach (Edge incoming in ascendant.Incomings)
{
// We needn't check the "supertree", as we are already iterating over ascendants, hence
- // we are setting that parameter to empty collections.
+ // we are setting that parameter to empty collections.
// Since the only change in this operation will be the additional subtree rooted by `child`,
// we only need to compare this outgoing edge by that subtree.
AssertNotRedundant(incoming.Source, incoming.Target, incoming.Type,
@@ -694,7 +695,7 @@ public void UnparentInArchitecture(Node child)
child.Reparent(null);
}
-
+
#region Helper
///
@@ -754,7 +755,7 @@ private static PartitionedDependencies RefsInSubtree(Node root, Predicate
return new PartitionedDependencies(oc, ic, i);
}
-
+
///
/// Returns all allowed propagated dependencies of the subtree rooted by .
/// See for details.
@@ -794,7 +795,7 @@ private void RemoveMapsTo(Edge mapsTo)
List subtree = MappedSubtree(mapsTo.Source);
Unmap(subtree, mapsTo.Target);
Node implSourceParent = mapsTo.Source.Parent;
-
+
if (implSourceParent == null)
{
// If mapsTo.Source has no parent, all nodes in subtree are not mapped at all any longer.
@@ -1002,4 +1003,4 @@ private static void AssertOrThrow(bool condition, Func exception)
#endregion
}
-}
\ No newline at end of file
+}
diff --git a/Assets/SEE/Tools/ReflexionAnalysis/ReflexionAnalysis.cs b/Assets/SEE/Tools/ReflexionAnalysis/ReflexionAnalysis.cs
index 7ed8019509..99690a112e 100644
--- a/Assets/SEE/Tools/ReflexionAnalysis/ReflexionAnalysis.cs
+++ b/Assets/SEE/Tools/ReflexionAnalysis/ReflexionAnalysis.cs
@@ -208,6 +208,19 @@ public static bool IsSpecified(Edge edge)
return state == State.Specified || state == State.Convergent || state == State.Absent || state == State.AllowedAbsent;
}
+ ///
+ /// Returns true if is a divergent
+ /// edge (present in the implementation graph, but missing in
+ /// the architecture graph).
+ /// Precondition: must be in the implementation graph.
+ ///
+ /// architecture dependency
+ /// true if edge is a divergent architecture dependency
+ public static bool IsDivergent(Edge edge)
+ {
+ AssertOrThrow(edge.IsInReflexion(), () => new NotInSubgraphException(Implementation, edge));
+ return edge.State() == State.Divergent;
+ }
#endregion
#region Edge counter attribute
@@ -1425,4 +1438,4 @@ public static void DumpTable(Dictionary table)
#endregion
}
-}
\ No newline at end of file
+}
diff --git a/Assets/SEE/Tools/ReflexionAnalysis/ReflexionGraph.cs b/Assets/SEE/Tools/ReflexionAnalysis/ReflexionGraph.cs
index 368852b9c9..45eb288c75 100644
--- a/Assets/SEE/Tools/ReflexionAnalysis/ReflexionGraph.cs
+++ b/Assets/SEE/Tools/ReflexionAnalysis/ReflexionGraph.cs
@@ -72,7 +72,7 @@ public ReflexionGraph(Graph implementation, Graph architecture, Graph mapping, s
///
/// This does not really run the reflexion analysis. Use to start the analysis.
///
- public ReflexionGraph(Graph fullGraph, bool allowDependenciesToParents = true): base(fullGraph)
+ public ReflexionGraph(Graph fullGraph, bool allowDependenciesToParents = true) : base(fullGraph)
{
AllowDependenciesToParents = allowDependenciesToParents;
(Graph implementation, Graph architecture, _) = Disassemble();
diff --git a/Assets/SEE/Utils/ActionHistory.cs b/Assets/SEE/Utils/ActionHistory.cs
index 9d087821d9..728cadee04 100644
--- a/Assets/SEE/Utils/ActionHistory.cs
+++ b/Assets/SEE/Utils/ActionHistory.cs
@@ -68,7 +68,7 @@ public class ActionHistory
///
/// An entry describing an executed action in the global action history.
///
- public struct GlobalHistoryEntry
+ public readonly struct GlobalHistoryEntry
{
///
/// Represents an entry in the globalHistory.
diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json
index 179e5a56ab..dbf44ff2f8 100644
--- a/Packages/packages-lock.json
+++ b/Packages/packages-lock.json
@@ -302,7 +302,7 @@
}
},
"com.unity.xr.core-utils": {
- "version": "2.2.1",
+ "version": "2.2.2",
"depth": 1,
"source": "registry",
"dependencies": {