diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFEdgeLink.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFEdgeLink.cs index ee0ae20b184ac1c30465b2648b31a727a4222bb4..1f39c84b149e444f415e87761726a7f06fe368f1 100644 --- a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFEdgeLink.cs +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFEdgeLink.cs @@ -22,6 +22,7 @@ namespace Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Graph public void clicked() { + Debug.Log(worldLink.ToJson()); NodeEditorWindow.ShowWindow(this); } } diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFGraphView.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFGraphView.cs index b85f7c825d3198f6b92821b81c93383f28554d8b..6cd3ad9093b15a5d3633ee6b6c15408012b222b7 100644 --- a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFGraphView.cs +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFGraphView.cs @@ -76,7 +76,7 @@ namespace ETSI.ARF.WorldStorage.UI { if (SaveInfo.instance.elemsToRemove == null) { - SaveInfo.instance.elemsToRemove = new List<string>(); + SaveInfo.instance.elemsToRemove = new Dictionary<string, Type>(); } foreach (GraphElement elt in selection.ToArray()) { @@ -86,7 +86,7 @@ namespace ETSI.ARF.WorldStorage.UI nodeAnchor.DisconnectAllPorts(this); if (SaveInfo.instance.nodePositions.ContainsKey(nodeAnchor.GUID)) { - SaveInfo.instance.elemsToRemove.Add(nodeAnchor.GUID); + SaveInfo.instance.elemsToRemove.Add(nodeAnchor.GUID, typeof(WorldAnchor)); } RemoveElement(elt); continue; @@ -97,7 +97,7 @@ namespace ETSI.ARF.WorldStorage.UI nodeTrackable.DisconnectAllPorts(this); if (SaveInfo.instance.nodePositions.ContainsKey(nodeTrackable.GUID)) { - SaveInfo.instance.elemsToRemove.Add(nodeTrackable.GUID); + SaveInfo.instance.elemsToRemove.Add(nodeTrackable.GUID, typeof(Trackable)); } RemoveElement(elt); continue; @@ -107,7 +107,7 @@ namespace ETSI.ARF.WorldStorage.UI { edgeLink.input.Disconnect(edgeLink); edgeLink.output.Disconnect(edgeLink); - SaveInfo.instance.elemsToRemove.Add(edgeLink.GUID); + SaveInfo.instance.elemsToRemove.Add(edgeLink.GUID, typeof(WorldLink)); RemoveElement(elt); continue; } @@ -123,9 +123,9 @@ namespace ETSI.ARF.WorldStorage.UI evt.menu.AppendSeparator(); evt.menu.AppendAction("Reload graph", delegate { - if (positionshaveBeenChanged() && EditorUtility.DisplayDialog("Saving node positions", "The nodes positions have been changed, would you like to save them ?", "Yes", "No")) + if (ServerAndLocalDifferent() && EditorUtility.DisplayDialog("Saving node positions", "The World Graph has been modified. \nWould you like to push the modifications to the server ?", "Yes", "No")) { - saveElemPositionsInServer(); + saveInServer(); } reload(); SaveInfo.instance.toReFrame = true; @@ -185,9 +185,10 @@ namespace ETSI.ARF.WorldStorage.UI { } } - private bool positionshaveBeenChanged() + + public bool ServerAndLocalDifferent() { - if (SaveInfo.instance.elemsToRemove.Count != 0) + if ((SaveInfo.instance.elemsToRemove.Count != 0) || (SaveInfo.instance.elemsToUpdate.Count != 0)) { return true; } @@ -195,9 +196,23 @@ namespace ETSI.ARF.WorldStorage.UI { float nodeX = node.GetPosition().x; float nodeY = node.GetPosition().y; - float dataX = SaveInfo.instance.nodePositions[node.GUID].x; - float dataY = SaveInfo.instance.nodePositions[node.GUID].y; - if ((nodeX != dataX) || (nodeY != dataY)) + if (!SaveInfo.instance.nodePositions.ContainsKey(node.GUID)) + { + return true; + } + else + { + float dataX = SaveInfo.instance.nodePositions[node.GUID].x; + float dataY = SaveInfo.instance.nodePositions[node.GUID].y; + if ((nodeX != dataX) || (nodeY != dataY)) + { + return true; + } + } + } + foreach (ARFEdgeLink edge in edges) + { + if (!SaveInfo.instance.linkIds.Contains(edge.GUID)) { return true; } @@ -225,7 +240,7 @@ namespace ETSI.ARF.WorldStorage.UI { var waNode = new ARFNodeWorldAnchor(worldAnchor); - Rect posTemp = new Rect(26, 93, 160, 77); + Rect posTemp = new(26, 93, 160, 77); SaveInfo.instance.nodePositions.TryGetValue(worldAnchor.UUID.ToString(), out posTemp); waNode.SetPosition(posTemp); @@ -236,7 +251,7 @@ namespace ETSI.ARF.WorldStorage.UI { var tracknode = new ARFNodeTrackable(trackable); - Rect posTemp = new Rect(26, 93, 160, 77); + Rect posTemp = new(26, 93, 160, 77); SaveInfo.instance.nodePositions.TryGetValue(trackable.UUID.ToString(), out posTemp); tracknode.SetPosition(posTemp); @@ -427,14 +442,64 @@ namespace ETSI.ARF.WorldStorage.UI return a = Mathf.Round(a * 2f) * 0.5f; } - public void saveElemPositionsInServer() + //Save all modified/deleted/added elements to the server + public void saveInServer() { foreach (ARFNode node in nodes) { if (!SaveInfo.instance.nodePositions.ContainsKey(node.GUID)) { - //TODO - Debug.Log("need to post " + node.GUID); + //POST TRACKABLE + if (node is ARFNodeTrackable aRFNodeTrackable) + { + var posX = new List<String>(); + posX.Add(aRFNodeTrackable.GetPosition().x.ToString()); + var posY = new List<String>(); + posY.Add(aRFNodeTrackable.GetPosition().y.ToString()); + Trackable trackable = aRFNodeTrackable.trackable; + trackable.KeyvalueTags["unityAuthoringPosX"] = posX; + trackable.KeyvalueTags["unityAuthoringPosY"] = posY; + String uuid = TrackableRequest.AddTrackable(worldStorageServer, trackable); + + //change the uuid in its edges, if there is a new edge to be added in the world storage it needs to have the correct uuid + uuid = uuid.Replace("\"", ""); + foreach (ARFEdgeLink edge in aRFNodeTrackable.portIn.connections) + { + edge.worldLink.UUIDTo = Guid.Parse(uuid); + } + foreach (ARFEdgeLink edge in aRFNodeTrackable.portOut.connections) + { + edge.worldLink.UUIDFrom = Guid.Parse(uuid); + } + aRFNodeTrackable.trackable.UUID = Guid.Parse(uuid); + aRFNodeTrackable.GUID = uuid; + } + //POST WORLDANCHOR + if (node is ARFNodeWorldAnchor aRFNodeWorldAnchor) + { + var posX = new List<String>(); + posX.Add(aRFNodeWorldAnchor.GetPosition().x.ToString()); + var posY = new List<String>(); + posY.Add(aRFNodeWorldAnchor.GetPosition().y.ToString()); + WorldAnchor worldAnchor = aRFNodeWorldAnchor.worldAnchor; + worldAnchor.KeyvalueTags["unityAuthoringPosX"] = posX; + worldAnchor.KeyvalueTags["unityAuthoringPosY"] = posY; + + String uuid = WorldAnchorRequest.AddWorldAnchor(worldStorageServer, worldAnchor); + + //change the uuid in its edges, if there is a new edge to be added in the world storage it needs to have the correct uuid + uuid = uuid.Replace("\"",""); + foreach (ARFEdgeLink edge in aRFNodeWorldAnchor.portIn.connections) + { + edge.worldLink.UUIDTo = Guid.Parse(uuid); + } + foreach (ARFEdgeLink edge in aRFNodeWorldAnchor.portOut.connections) + { + edge.worldLink.UUIDFrom = Guid.Parse(uuid); + } + aRFNodeWorldAnchor.worldAnchor.UUID = Guid.Parse(uuid); + aRFNodeWorldAnchor.GUID = uuid; + } } else { @@ -442,26 +507,74 @@ namespace ETSI.ARF.WorldStorage.UI float yLocal = node.GetPosition().y; float xServer = SaveInfo.instance.nodePositions[node.GUID].x; ; float yServer = SaveInfo.instance.nodePositions[node.GUID].y; - if ((xLocal != xServer) && (yLocal != yServer)) + if (((xLocal != xServer) || (yLocal != yServer)) || SaveInfo.instance.elemsToUpdate.Contains(node.GUID)) { - //TODO - Debug.Log("need to update " + node.GUID); + if(node is ARFNodeTrackable aRFNodeTrackable) + { + var posX = new List<String>(); + posX.Add(aRFNodeTrackable.GetPosition().x.ToString()); + var posY = new List<String>(); + posY.Add(aRFNodeTrackable.GetPosition().y.ToString()); + Trackable trackable = aRFNodeTrackable.trackable; + trackable.KeyvalueTags["unityAuthoringPosX"] = posX; + trackable.KeyvalueTags["unityAuthoringPosY"] = posY; + TrackableRequest.UpdateTrackable(worldStorageServer, trackable); + } + if (node is ARFNodeWorldAnchor aRFNodeWorldAnchor) + { + var posX = new List<String>(); + posX.Add(aRFNodeWorldAnchor.GetPosition().x.ToString()); + var posY = new List<String>(); + posY.Add(aRFNodeWorldAnchor.GetPosition().y.ToString()); + WorldAnchor worldAnchor = aRFNodeWorldAnchor.worldAnchor; + worldAnchor.KeyvalueTags["unityAuthoringPosX"] = posX; + worldAnchor.KeyvalueTags["unityAuthoringPosY"] = posY; + WorldAnchorRequest.UpdateWorldAnchor(worldStorageServer, worldAnchor); + } } } } foreach (ARFEdgeLink edge in edges) { - if (!SaveInfo.instance.linkIds.Contains(edge.GUID)) + if (edge is ARFEdgeLink aRFEdgeLink) { - //TODO - Debug.Log("need to post link between " + edge.input); + if (!SaveInfo.instance.linkIds.Contains(aRFEdgeLink.GUID)) + { + WorldLink worldLink = aRFEdgeLink.worldLink; + string uuid = WorldLinkRequest.AddWorldLink(worldStorageServer, worldLink); + uuid = uuid.Replace("\"", ""); + + aRFEdgeLink.worldLink.UUID = Guid.Parse(uuid); + aRFEdgeLink.GUID = uuid; + } + else if (SaveInfo.instance.elemsToUpdate.Contains(aRFEdgeLink.GUID)) + { + WorldLink worldLink = aRFEdgeLink.worldLink; + WorldLinkRequest.UpdateWorldLink(worldStorageServer, worldLink); + } } } - foreach (String elemId in SaveInfo.instance.elemsToRemove) + //DELETE ELEMENTS FROM THE SERVER + foreach (KeyValuePair<String, Type> elemToRemove in SaveInfo.instance.elemsToRemove) { - //TODO - Debug.Log("need to remove " + elemId); + string typeName = elemToRemove.Value.Name; + switch (typeName) + { + case nameof(Trackable): + TrackableRequest.DeleteTrackable(worldStorageServer, elemToRemove.Key); + break; + case nameof(WorldAnchor): + WorldAnchorRequest.DeleteWorldAnchor(worldStorageServer, elemToRemove.Key); + break; + case nameof(WorldLink): + WorldLinkRequest.DeleteWorldLink(worldStorageServer, elemToRemove.Key); + break; + default: + Debug.Log("oops"); + break; + } } + SaveInfo.instance.initNodePos(worldStorageServer, worldStorageUser); } } } \ No newline at end of file diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNode.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNode.cs index 6c29371aa286dcbe0f9fccb5581906357972b2f8..fb3eb4e9d56ded0e5e164a43be766770573b83cf 100644 --- a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNode.cs +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNode.cs @@ -39,27 +39,26 @@ using System; namespace ETSI.ARF.WorldStorage.UI { - public class ARFNode : Node + public abstract class ARFNode : Node { public string GUID; public bool entryPoint = false; - public Port portOut; - public Port portIn; + public ARFPort portOut; + public ARFPort portIn; public GUID id; public ARFNode() { } - public override Port InstantiatePort(Orientation orientation, Direction direction, Port.Capacity capacity, Type type) { switch (direction) { case Direction.Input: - portIn = Port.Create<ARFEdgeLink>(orientation, direction, capacity, type); + portIn = ARFPort.CreateARF<ARFEdgeLink>(orientation, direction, capacity, type); return portIn; case Direction.Output: - portOut = Port.Create<ARFEdgeLink>(orientation, direction, capacity, type); + portOut = ARFPort.CreateARF<ARFEdgeLink>(orientation, direction, capacity, type); return portOut; default: return null; @@ -99,5 +98,7 @@ namespace ETSI.ARF.WorldStorage.UI { return node.InstantiatePort(Orientation.Horizontal, portDirection, capacity, typeof(int)); // dummy } + + public abstract ObjectType GetElemType(); } } \ No newline at end of file diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeTrackable.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeTrackable.cs index b25b58e73ca7634a46e7f81d957dce74cf21516d..ebc1646a9bcde7ec56711cdb5ad6412e57cecc01 100644 --- a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeTrackable.cs +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeTrackable.cs @@ -60,13 +60,13 @@ namespace ETSI.ARF.WorldStorage.UI var portIn = GeneratePort(this, Direction.Input, Port.Capacity.Multi); portIn.portColor = new Color(0.77f, 0.77f, 0.77f, 0.77f); portIn.portName = "Target"; // "Input" - portIn.AddManipulator(new EdgeConnector<ARFEdgeLink>(new WorldLinkListener())); + //portIn.AddManipulator(new EdgeConnector<ARFEdgeLink>(new WorldLinkListener())); inputContainer.Add(portIn); var portOut = GeneratePort(this, Direction.Output, Port.Capacity.Multi); portOut.portColor = new Color(0.77f, 0.77f, 0.77f, 0.77f); portOut.portName = "Source"; // "Output"; - portOut.AddManipulator(new EdgeConnector<ARFEdgeLink>(new WorldLinkListener())); ; + //portOut.AddManipulator(new EdgeConnector<ARFEdgeLink>(new WorldLinkListener())); ; outputContainer.Add(portOut); RefreshExpandedState(); @@ -84,5 +84,9 @@ namespace ETSI.ARF.WorldStorage.UI NodeEditorWindow.ShowWindow(this); Debug.Log(trackable.ToString()); } + public override ObjectType GetElemType() + { + return ObjectType.Trackable; + } } } \ No newline at end of file diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeWorldAnchor.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeWorldAnchor.cs index a8c83a337c3360a7aca0de47a04a881c8001e55a..4c272f906ad305c1c2fca99208225bbc6519b8ba 100644 --- a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeWorldAnchor.cs +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeWorldAnchor.cs @@ -60,13 +60,13 @@ namespace ETSI.ARF.WorldStorage.UI var portIn = GeneratePort(this, Direction.Input, Port.Capacity.Multi); portIn.portColor = new Color(0.77f,0.77f,0.77f, 0.77f); portIn.portName = "Target"; // "Input"; - portIn.AddManipulator(new EdgeConnector<ARFEdgeLink>(new WorldLinkListener())); + //portIn.AddManipulator(new EdgeConnector<ARFEdgeLink>(new WorldLinkListener())); inputContainer.Add(portIn); var portOut = GeneratePort(this, Direction.Output, Port.Capacity.Multi); portOut.portColor = new Color(0.77f, 0.77f, 0.77f, 0.77f); portOut.portName = "Source"; // "Output"; - portOut.AddManipulator(new EdgeConnector<ARFEdgeLink>(new WorldLinkListener())); + //portOut.AddManipulator(new EdgeConnector<ARFEdgeLink>(new WorldLinkListener())); outputContainer.Add(portOut); RefreshExpandedState(); @@ -84,5 +84,9 @@ namespace ETSI.ARF.WorldStorage.UI Debug.Log(worldAnchor.ToString()); NodeEditorWindow.ShowWindow(this); } + public override ObjectType GetElemType() + { + return ObjectType.WorldAnchor; + } } } \ No newline at end of file diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFPort.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFPort.cs new file mode 100644 index 0000000000000000000000000000000000000000..faa80776654773811633e56a7ce197debacc3a16 --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFPort.cs @@ -0,0 +1,49 @@ +using Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows; +using ETSI.ARF.WorldStorage.UI; +using Org.OpenAPITools.Model; +using System; +using System.Collections.Generic; +using UnityEditor; +using UnityEditor.Experimental.GraphView; +using UnityEngine; +using UnityEngine.UIElements; + +namespace Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Graph +{ + public class ARFPort : Port + { + protected ARFPort(Orientation portOrientation, Direction portDirection, Capacity portCapacity, Type type) : base(portOrientation, portDirection, portCapacity, type) + { + } + + public override void Connect(Edge edge) + { + base.Connect(edge); + ARFNode fromNode = edge.output.node as ARFNode; + ARFNode toNode = edge.input.node as ARFNode; + + if (edge is ARFEdgeLink aRFedge) + { + List<float> transform = new List<float>(); + for (int i = 0; i < 16; i++) + { + transform.Add(0); + } + + WorldLink worldLink = new WorldLink(Guid.NewGuid(), Guid.Parse(SaveInfo.instance.worldStorageUser.UUID), Guid.Parse(fromNode.GUID), Guid.Parse(toNode.GUID), fromNode.GetElemType(), toNode.GetElemType(), transform, UnitSystem.CM, new Dictionary<string, List<string>>()); + aRFedge.worldLink = worldLink; + } + } + + public static ARFPort CreateARF<TEdge>(Orientation orientation, Direction direction, Capacity capacity, Type type) where TEdge : Edge, new() + { + WorldLinkListener listener = new WorldLinkListener(); + ARFPort port = new(orientation, direction, capacity, type) + { + m_EdgeConnector = new EdgeConnector<TEdge>(listener) + }; + port.AddManipulator(port.m_EdgeConnector); + return port; + } + } +} \ No newline at end of file diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFPort.cs.meta b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFPort.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..6d043fde500829981fc15944de7d1198cb5e1375 --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFPort.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3c67fa4402011954bb65be6215d52512 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/GraphWindow.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/GraphWindow.cs index 9c496ee89040237b46e84b324ab9267529fc7529..8d70a34a0d72dd8522b941fe4fae238734c13921 100644 --- a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/GraphWindow.cs +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/GraphWindow.cs @@ -41,6 +41,8 @@ using IO.Swagger.Model; #endif +//THIS CLASS IS GOING TO BE DELETED !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + namespace ETSI.ARF.WorldStorage.UI { diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/WorldLinkListener.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/WorldLinkListener.cs index 36c855f14fcdcc3827aed119132b75f97ead4322..79b691491118da7fa2910789ad10db351a5a79fe 100644 --- a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/WorldLinkListener.cs +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/WorldLinkListener.cs @@ -1,22 +1,76 @@ using Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows; using ETSI.ARF.WorldStorage; using ETSI.ARF.WorldStorage.UI; +using Org.OpenAPITools.Model; +using System; +using System.Collections.Generic; using UnityEditor; using UnityEditor.Experimental.GraphView; using UnityEngine; using UnityEngine.UIElements; +using static UnityEditor.Experimental.GraphView.Port; namespace Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Graph { public class WorldLinkListener : IEdgeConnectorListener { + private GraphViewChange m_GraphViewChange; + + private List<Edge> m_EdgesToCreate; + + private List<GraphElement> m_EdgesToDelete; + + public WorldLinkListener() + { + m_EdgesToCreate = new List<Edge>(); + m_EdgesToDelete = new List<GraphElement>(); + m_GraphViewChange.edgesToCreate = m_EdgesToCreate; + } public void OnDrop(GraphView graphView, Edge edge) { - ARFNode fromNode = edge.output.node as ARFNode; - ARFNode toNode = edge.input.node as ARFNode; + m_EdgesToCreate.Clear(); + m_EdgesToCreate.Add(edge); + m_EdgesToDelete.Clear(); + if (edge.input.capacity == Capacity.Single) + { + foreach (Edge connection in edge.input.connections) + { + if (connection != edge) + { + m_EdgesToDelete.Add(connection); + } + } + } + + if (edge.output.capacity == Capacity.Single) + { + foreach (Edge connection2 in edge.output.connections) + { + if (connection2 != edge) + { + m_EdgesToDelete.Add(connection2); + } + } + } + + if (m_EdgesToDelete.Count > 0) + { + graphView.DeleteElements(m_EdgesToDelete); + } + + List<Edge> edgesToCreate = m_EdgesToCreate; + if (graphView.graphViewChanged != null) + { + edgesToCreate = graphView.graphViewChanged(m_GraphViewChange).edgesToCreate; + } + foreach (Edge item in edgesToCreate) + { + graphView.AddElement(item); + edge.input.Connect(item); + edge.output.Connect(item); + } NodeEditorWindow.ShowWindow((ARFEdgeLink)edge); - //WorldLinkWindow.preFill(fromNode, toNode); } public void OnDropOutsidePort(Edge edge, Vector2 position) diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldGraphWindow.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldGraphWindow.cs index d20562f0cfcdcd47452acd25aadfeea9e3065e00..f32f961183efe7b4d8954d2168471260aeafcc02 100644 --- a/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldGraphWindow.cs +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldGraphWindow.cs @@ -19,6 +19,9 @@ namespace Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows private ARFGraphView myGraph; + //to delay the reframe (otherwise it reframes when the graph isn't built yet) + int twoFrames = 0; + [MenuItem("ARFWorldStorage/Edit Graph...")] public static void ShowWindow() { @@ -27,13 +30,13 @@ namespace Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows public void OnEnable() { - if (SaveInfo.instance.nodePositions == null) - { - SaveInfo.instance.initNodePos(worldStorageServer); - } rootVisualElement.Add(GenerateToolbar()); + if (SaveInfo.instance.nodePositions == null) + { + SaveInfo.instance.initNodePos(worldStorageServer, worldStorageUser); + } ConstructGraphView(); myGraph.style.top = Length.Percent(11); rootVisualElement.Add(myGraph); @@ -58,6 +61,11 @@ namespace Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows void OnGUI() { + if (SaveInfo.instance.nodePositions == null) + { + SaveInfo.instance.initNodePos(worldStorageServer, worldStorageUser); + } + EditorGUILayout.BeginVertical(); EditorGUILayout.Space(24); @@ -65,11 +73,13 @@ namespace Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows worldStorageServer = (WorldStorageServer)EditorGUILayout.ObjectField("World Storage Server", worldStorageServer, typeof(WorldStorageServer), false, GUILayout.Width(500)); if (EditorGUI.EndChangeCheck()) { - myGraph.saveElemPositionsInServer(); + if (myGraph.ServerAndLocalDifferent() && EditorUtility.DisplayDialog("Saving node positions", "The World Graph has been modified. \nWould you like to push the modifications to the server ?", "Yes", "No")) + { + myGraph.saveInServer(); + } rootVisualElement.Remove(myGraph); - SaveInfo.instance.initNodePos(worldStorageServer); - + SaveInfo.instance.initNodePos(worldStorageServer, worldStorageUser); ConstructGraphView(); myGraph.style.top = Length.Percent(11); rootVisualElement.Add(myGraph); @@ -77,36 +87,19 @@ namespace Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows //reframe all elements to see them all - if (SaveInfo.instance.toReFrame) + if (SaveInfo.instance.toReFrame && (twoFrames == 2)) { myGraph.FrameAllElements(); SaveInfo.instance.toReFrame = false; + twoFrames = 0; } - EditorGUILayout.EndVertical(); - } - private bool localAndServerDifferent() - { - foreach (ARFNode node in myGraph.nodes) + else if (SaveInfo.instance.toReFrame) { - float nodeX = node.GetPosition().x; - float nodeY = node.GetPosition().y; - if (SaveInfo.instance.nodePositions.ContainsKey(node.GUID)){ - float dataX = SaveInfo.instance.nodePositions[node.GUID].x; - float dataY = SaveInfo.instance.nodePositions[node.GUID].y; - if ((nodeX != dataX) || (nodeY != dataY)) - { - return true; - } - } - else - { - return true; - } + twoFrames++; } - return false; + EditorGUILayout.EndVertical(); } - //generate the window's top toolbar private Toolbar GenerateToolbar() { @@ -137,7 +130,7 @@ namespace Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows var save = new Button(clickEvent: () => { - myGraph.saveElemPositionsInServer(); + myGraph.saveInServer(); }) { text = "Save" @@ -154,16 +147,19 @@ namespace Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows public Dictionary<String, Rect> nodePositions; public List<String> linkIds; - public List<String> elemsToRemove; + public Dictionary<String,Type> elemsToRemove; + public List<String> elemsToUpdate; //keep the info of the graph reframe public Boolean toReFrame = false; public WorldStorageServer worldStorageServer; + public WorldStorageUser worldStorageUser; - public void initNodePos(WorldStorageServer server) + public void initNodePos(WorldStorageServer server, WorldStorageUser user) { worldStorageServer = server; + worldStorageUser = user; instance.nodePositions = new Dictionary<string, Rect>(); foreach (Trackable track in TrackableRequest.GetAllTrackables(worldStorageServer)) @@ -172,12 +168,12 @@ namespace Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows { var posX = RoundToNearestHalf(float.Parse(track.KeyvalueTags["unityAuthoringPosX"][0])); var posY = RoundToNearestHalf(float.Parse(track.KeyvalueTags["unityAuthoringPosY"][0])); - Rect trackPos = new Rect(posX, posY, 135, 77); + Rect trackPos = new(posX, posY, 135, 77); instance.nodePositions[track.UUID.ToString()] = trackPos; } else { - Rect trackPos = new Rect(0, 0, 135, 77); + Rect trackPos = new(0, 0, 135, 77); instance.nodePositions[track.UUID.ToString()] = trackPos; } } @@ -187,12 +183,12 @@ namespace Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows { var posX = RoundToNearestHalf(float.Parse(wa.KeyvalueTags["unityAuthoringPosX"][0])); var posY = RoundToNearestHalf(float.Parse(wa.KeyvalueTags["unityAuthoringPosY"][0])); - Rect waPos = new Rect(posX, posY, 135, 77); + Rect waPos = new(posX, posY, 135, 77); instance.nodePositions[wa.UUID.ToString()] = waPos; } else { - Rect trackPos = new Rect(0, 0, 135, 77); + Rect trackPos = new(0, 0, 135, 77); instance.nodePositions[wa.UUID.ToString()] = trackPos; } } @@ -202,9 +198,10 @@ namespace Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows { instance.linkIds.Add(link.UUID.ToString()); } - instance.toReFrame = true; - instance.elemsToRemove = new List<string>(); + instance.toReFrame = true; + instance.elemsToRemove = new Dictionary<string, Type>(); + instance.elemsToUpdate = new List<string>(); } //method to predict the position of a node (the float that will be saved in the PositionInfo singleton) @@ -212,7 +209,5 @@ namespace Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows { return a = Mathf.Round(a * 2f) * 0.5f; } - - } } \ No newline at end of file diff --git a/UserSettings/Layouts/default-2021.dwlt b/UserSettings/Layouts/default-2021.dwlt index aff4bb35650cf53043c42f28eca027b3561aa8af..ac8618fa07b3acdd61c12f58faec880a2e0e50c4 100644 --- a/UserSettings/Layouts/default-2021.dwlt +++ b/UserSettings/Layouts/default-2021.dwlt @@ -48,7 +48,7 @@ MonoBehaviour: m_MinSize: {x: 300, y: 200} m_MaxSize: {x: 24288, y: 16192} vertical: 0 - controlID: 15 + controlID: 50 --- !u!114 &3 MonoBehaviour: m_ObjectHideFlags: 52 @@ -70,10 +70,10 @@ MonoBehaviour: height: 768 m_MinSize: {x: 101, y: 121} m_MaxSize: {x: 4001, y: 4021} - m_ActualView: {fileID: 12} + m_ActualView: {fileID: 13} m_Panes: - {fileID: 15} - - {fileID: 12} + - {fileID: 13} m_Selected: 1 m_LastSelected: 1 --- !u!114 &4 @@ -93,10 +93,10 @@ MonoBehaviour: serializedVersion: 2 x: 0 y: 0 - width: 314 + width: 313 height: 455 - m_MinSize: {x: 201, y: 221} - m_MaxSize: {x: 4001, y: 4021} + m_MinSize: {x: 200, y: 200} + m_MaxSize: {x: 4000, y: 4000} m_ActualView: {fileID: 16} m_Panes: - {fileID: 16} @@ -224,7 +224,7 @@ MonoBehaviour: m_MinSize: {x: 200, y: 200} m_MaxSize: {x: 16192, y: 16192} vertical: 1 - controlID: 83 + controlID: 51 --- !u!114 &10 MonoBehaviour: m_ObjectHideFlags: 52 @@ -249,7 +249,7 @@ MonoBehaviour: m_MinSize: {x: 200, y: 100} m_MaxSize: {x: 16192, y: 8096} vertical: 0 - controlID: 84 + controlID: 52 --- !u!114 &11 MonoBehaviour: m_ObjectHideFlags: 52 @@ -265,19 +265,19 @@ MonoBehaviour: m_Children: [] m_Position: serializedVersion: 2 - x: 314 + x: 313 y: 0 - width: 872 + width: 873 height: 455 m_MinSize: {x: 102, y: 121} m_MaxSize: {x: 4002, y: 4021} - m_ActualView: {fileID: 13} + m_ActualView: {fileID: 12} m_Panes: - {fileID: 17} - {fileID: 18} - - {fileID: 13} + - {fileID: 12} m_Selected: 2 - m_LastSelected: 2 + m_LastSelected: 1 --- !u!114 &12 MonoBehaviour: m_ObjectHideFlags: 52 @@ -287,26 +287,27 @@ MonoBehaviour: m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: e219817d65c8b1f40ad85e6185e89e92, type: 3} + m_Script: {fileID: 11500000, guid: 2c1a0c92306453d46897c1af6cb5c2f9, type: 3} m_Name: m_EditorClassIdentifier: m_MinSize: {x: 100, y: 100} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: - m_Text: Trackable Editor + m_Text: Graph Editor m_Image: {fileID: 0} m_Tooltip: m_Pos: serializedVersion: 2 - x: 1186 + x: 313 y: 72 - width: 413 - height: 747 + width: 871 + height: 434 m_ViewDataDictionary: {fileID: 0} m_OverlayCanvas: m_LastAppliedPresetName: Default m_SaveData: [] - type: 2 + worldStorageServer: {fileID: 11400000, guid: 777684ed8f62c9d408a1813e8382c676, type: 2} + worldStorageUser: {fileID: 11400000, guid: c0696089e4a855b46ad490437919b1e8, type: 2} --- !u!114 &13 MonoBehaviour: m_ObjectHideFlags: 52 @@ -316,27 +317,26 @@ MonoBehaviour: m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 2c1a0c92306453d46897c1af6cb5c2f9, type: 3} + m_Script: {fileID: 11500000, guid: e219817d65c8b1f40ad85e6185e89e92, type: 3} m_Name: m_EditorClassIdentifier: m_MinSize: {x: 100, y: 100} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: - m_Text: Graph Editor + m_Text: Trackable Editor m_Image: {fileID: 0} m_Tooltip: m_Pos: serializedVersion: 2 - x: 314 + x: 1186 y: 72 - width: 870 - height: 434 + width: 413 + height: 747 m_ViewDataDictionary: {fileID: 0} m_OverlayCanvas: m_LastAppliedPresetName: Default m_SaveData: [] - worldStorageServer: {fileID: 11400000, guid: 3a9ba82f4e8dd124ca2b005861c64d01, type: 2} - worldStorageUser: {fileID: 11400000, guid: c0696089e4a855b46ad490437919b1e8, type: 2} + type: 0 --- !u!114 &14 MonoBehaviour: m_ObjectHideFlags: 52 @@ -393,7 +393,7 @@ MonoBehaviour: scrollPos: {x: 0, y: 0} m_SelectedIDs: 644b0000 m_LastClickedID: 19300 - m_ExpandedIDs: 00000000504b0000524b0000544b0000564b000000ca9a3bffffff7f + m_ExpandedIDs: 00000000524b0000544b0000564b0000584b0000 m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: @@ -421,7 +421,7 @@ MonoBehaviour: scrollPos: {x: 0, y: 0} m_SelectedIDs: m_LastClickedID: 0 - m_ExpandedIDs: 00000000504b0000524b0000544b0000564b0000 + m_ExpandedIDs: 00000000524b0000544b0000564b0000584b0000 m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: @@ -511,7 +511,7 @@ MonoBehaviour: m_CachedPref: 160 m_ControlHash: -371814159 m_PrefName: Preview_InspectorPreview - m_LastInspectedObjectInstanceID: 3288 + m_LastInspectedObjectInstanceID: 19264 m_LastVerticalScrollValue: 0 m_GlobalObjectId: m_InspectorMode: 0 @@ -540,7 +540,7 @@ MonoBehaviour: serializedVersion: 2 x: 0 y: 72 - width: 313 + width: 312 height: 434 m_ViewDataDictionary: {fileID: 0} m_OverlayCanvas: @@ -549,7 +549,7 @@ MonoBehaviour: m_SceneHierarchy: m_TreeViewState: scrollPos: {x: 0, y: 0} - m_SelectedIDs: d80c0000 + m_SelectedIDs: 404b0000 m_LastClickedID: 0 m_ExpandedIDs: 38fbffff m_RenameOverlay: @@ -900,10 +900,10 @@ MonoBehaviour: m_Tooltip: m_Pos: serializedVersion: 2 - x: 507 - y: 94 - width: 1532 - height: 790 + x: 313 + y: 72 + width: 871 + height: 434 m_ViewDataDictionary: {fileID: 0} m_OverlayCanvas: m_LastAppliedPresetName: Default @@ -914,10 +914,10 @@ MonoBehaviour: m_ShowGizmos: 0 m_TargetDisplay: 0 m_ClearColor: {r: 0, g: 0, b: 0, a: 0} - m_TargetSize: {x: 1532, y: 769} + m_TargetSize: {x: 871, y: 413} m_TextureFilterMode: 0 m_TextureHideFlags: 61 - m_RenderIMGUI: 0 + m_RenderIMGUI: 1 m_EnterPlayModeBehavior: 0 m_UseMipMap: 0 m_VSyncEnabled: 0 @@ -929,10 +929,10 @@ MonoBehaviour: m_VRangeLocked: 0 hZoomLockedByDefault: 0 vZoomLockedByDefault: 0 - m_HBaseRangeMin: -383 - m_HBaseRangeMax: 383 - m_VBaseRangeMin: -192.25 - m_VBaseRangeMax: 192.25 + m_HBaseRangeMin: -217.75 + m_HBaseRangeMax: 217.75 + m_VBaseRangeMin: -103.25 + m_VBaseRangeMax: 103.25 m_HAllowExceedBaseRangeMin: 1 m_HAllowExceedBaseRangeMax: 1 m_VAllowExceedBaseRangeMin: 1 @@ -950,23 +950,23 @@ MonoBehaviour: serializedVersion: 2 x: 0 y: 21 - width: 1532 - height: 769 + width: 871 + height: 413 m_Scale: {x: 2, y: 2} - m_Translation: {x: 766, y: 384.5} + m_Translation: {x: 435.5, y: 206.5} m_MarginLeft: 0 m_MarginRight: 0 m_MarginTop: 0 m_MarginBottom: 0 m_LastShownAreaInsideMargins: serializedVersion: 2 - x: -383 - y: -192.25 - width: 766 - height: 384.5 + x: -217.75 + y: -103.25 + width: 435.5 + height: 206.5 m_MinimalGUI: 1 m_defaultScale: 2 - m_LastWindowPixelSize: {x: 3064, y: 1580} + m_LastWindowPixelSize: {x: 1742, y: 868} m_ClearInEditMode: 1 m_NoCameraWarning: 1 m_LowResolutionForAspectRatios: 01000000000000000000