private void AddSearchPathToEnvironment(CyPhyML.Component component, MetaLinkProtobuf.Environment env)
 {
     string path = Path.GetDirectoryName(GetCadModelPath(component));
     if (path == null)
     {
         GMEConsole.Warning.WriteLine(String.Format("MetaLink warning: component '{0}' has no modelpath in the manifest.project.json", component.Name));
     }
     else
     {
         env.value.Add(path);
     }
 }
 private void ProcessEditSelect(string assemblyId, MetaLinkProtobuf.Action action)
 {
     CyPhyML.ComponentRef compRef = null;
     if (action.payload.components.Count > 0 && String.IsNullOrEmpty(action.payload.components[0].ComponentID) == false)
     {
         addon.Project.BeginTransactionInNewTerr(transactiontype_enum.TRANSACTION_NON_NESTED);
         try
         {
             CyPhyML.ComponentAssembly assembly = CyphyMetaLinkUtils.GetComponentAssemblyByGuid(addon.Project, assemblyId);
             if (assembly != null)
             {
                 compRef = CyphyMetaLinkUtils.GetComponentRefInAssemblyById(assembly, action.payload.components[0].ComponentID);
             }
         }
         finally
         {
             addon.Project.CommitTransaction();
         }
     }
     if (compRef != null)
     {
         GMEConsole.gme.ShowFCO((MgaFCO)compRef.Impl, true);
     }
 }
 private void ProcessEditInsert(string componentAssemblyGuid, MetaLinkProtobuf.Action action)
 {
     addon.Project.BeginTransactionInNewTerr();
     try
     {
         CyPhyML.ComponentAssembly topicAssembly = CyphyMetaLinkUtils.GetComponentAssemblyByGuid(addon.Project, componentAssemblyGuid);
         foreach (var messageComponent in action.payload.components)
         {
             CyPhyML.Component referencedComponent = CyphyMetaLinkUtils.FindAVMComponent(addon.Project, messageComponent.AvmComponentID, null);
             if (referencedComponent == null)
             {
                 GMEConsole.Warning.WriteLine("Add component: can't find AVM component with id: " + messageComponent.AvmComponentID);
             }
             else if (topicAssembly != null) // TODO: log unknown component
             {
                 //MgaFCO newcompfco = ((MgaModel)assembly.Impl).DeriveChildObject((MgaFCO)referencedComponent.Impl, ((MgaMetaModel)assembly.Impl.MetaBase).RoleByName["Component"], true);
                 // MgaFCO newcompfco = ((MgaModel)assembly.Impl).CopyFCODisp((MgaFCO)referencedComponent.Impl, ((MgaMetaModel)assembly.Impl.MetaBase).RoleByName["Component"]);
                 var newcomp = CyPhyMLClasses.ComponentRef.Create(topicAssembly);
                 newcomp.Referred.Component = referencedComponent;
                 newcomp.Attributes.InstanceGUID = newcomp.Guid.ToString("D");
                 if (String.IsNullOrEmpty(messageComponent.Name))
                 {
                     newcomp.Name = referencedComponent.Name;
                 }
                 else
                 {
                     newcomp.Name = messageComponent.Name;
                 }
             }
             else
             {
                 GMEConsole.Warning.WriteLine("Add component: can't find design assembly with id: " + componentAssemblyGuid);
             }
         }
         addon.Project.CommitTransaction();
     }
     catch (Exception e)
     {
         addon.Project.AbortTransaction();
         GMEConsole.Out.WriteLine("Add component: Exception during inserting new component: {0}", System.Security.SecurityElement.Escape(e.ToString()));
     }
 }
 private void ProcessAVMComponentInsert(string avmid, MetaLinkProtobuf.Action action)
 {
     
     try
     {
         addon.Project.BeginTransactionInNewTerr();
         CyPhyML.Component component = CyphyMetaLinkUtils.GetComponentByAvmId(addon.Project, avmid);
         if (component == null)
         {
             GMEConsole.Error.WriteLine("Create connector: can't find component with AVMID " + avmid);
             addon.Project.AbortTransaction();
         } else {
             CyPhyML.CADModel cadModel = CyphyMetaLinkUtils.FindCADModelObject(component);
             if (cadModel == null)
             {
                 GMEConsole.Warning.WriteLine("Create connector: can't find cadmodel within component " + component.Name + " , skipping...");
                 addon.Project.AbortTransaction();
             }
             else
             {
                 // Insert new connectors
                 foreach (ConnectorType actionConnector in action.payload.connectors)
                 {
                     CyPhyML.Connector connector = null;
                     if (!String.IsNullOrEmpty(actionConnector.ID))
                     {
                         connector = CyphyMetaLinkUtils.FindConnector(component, actionConnector.ID);
                         if (connector == null)
                         {
                             GMEConsole.Warning.WriteLine("Create connector: can't find connector with id " + actionConnector.ID + " , skipping...");
                             continue;
                         }
                     }
                     List<CyPhyML.CADDatum> datumList = new List<CyPhyML.CADDatum>();
                     List<string> datumNamesList = new List<string>();
                     List<ConnectorDatumType.AlignType> datumAlignList = new List<ConnectorDatumType.AlignType>();
                     bool success = true;
                     foreach (var datum in actionConnector.Datums)
                     {
                         CyPhyML.CADDatum cadDatum = CyphyMetaLinkUtils.FindDatum(cadModel, datum.ID);
                         if (cadDatum == null)
                         {
                             GMEConsole.Warning.WriteLine("Create connector: can't find datum with name: " + datum.ID + " , skipping...");
                             success = false;
                             break;
                         }
                         datumList.Add(cadDatum);
                         datumNamesList.Add(datum.DisplayName);
                         datumAlignList.Add(datum.Alignment);
                     }
                     if (!success) continue;
                     CreateOrUpdateConnector(component, datumList, datumNamesList, datumAlignList, connector, connector==null?actionConnector.DisplayName:null);
                 }
                 addon.Project.CommitTransaction();
             }
         }
     }
     catch (Exception ex)
     {
         addon.Project.AbortTransaction();
         GMEConsole.Error.WriteLine("AVM Component Insert, exception caught: " + ex.Message);
     }
 }
 private void ProcessEditDiscard(string assemblyId, MetaLinkProtobuf.Action action)
 {
     try
     {
         handleEvents = false;
         addon.Project.BeginTransactionInNewTerr(transactiontype_enum.TRANSACTION_NON_NESTED);
         CyPhyML.ComponentAssembly assembly = CyphyMetaLinkUtils.GetComponentAssemblyByGuid(addon.Project, assemblyId);
         foreach (var component in action.payload.components)
         {
             CyPhyML.ComponentRef cref = CyphyMetaLinkUtils.GetComponentRefInAssemblyById(assembly, component.ComponentID);
             if (cref == null)
             {
                 GMEConsole.Warning.WriteLine("Remove component: Can't find component ref with id: " + component.ComponentID);
             }
             else
             {
                 cref.Delete();
             }
         }
         RestartAssemblySyncAtEndOfTransaction(assembly);
         addon.Project.CommitTransaction();
         handleEvents = true;
     }
     catch (Exception ex)
     {
         GMEConsole.Warning.WriteLine("Remove component: An exception happened while processing the request: " + ex.Message);
         addon.Project.AbortTransaction();
         handleEvents = true;
     }
 }
 private void ProcessAnalysisPointMessage(string avmid, MetaLinkProtobuf.Action action)
 {
     addon.Project.BeginTransactionInNewTerr();
     CyPhyML.Component component = CyphyMetaLinkUtils.GetComponentByAvmId(addon.Project, avmid);
     if (component == null)
     {
         GMEConsole.Error.WriteLine("Create connector: can't find component with AVMID " + avmid);
         addon.Project.AbortTransaction();
     }
     else
     {
         try
         {
             CyPhyML.CADModel cadmodel = CyphyMetaLinkUtils.FindCADModelObject(component);
             if (cadmodel == null)
             {
                 GMEConsole.Error.WriteLine("Can't find CADModel in component: " + component.ToHyperLink());
                 addon.Project.AbortTransaction();
                 return;
             }
             foreach (var datum in action.payload.datums)
             {
                 CyPhyML.Point point = CyPhyMLClasses.Point.Create(component);
                 point.Name = datum.name;
                 point.Attributes.ID = datum.name;
                 var connectdatum = cadmodel.Children.PointCollection.Where(p => p.ID == datum.name);
                 CyPhyML.Point datumPoint = null;
                 if (!connectdatum.Any())
                 {
                     datumPoint = CyPhyMLClasses.Point.Create(cadmodel);
                     datumPoint.Name = datumPoint.Attributes.DatumName = datum.name;
                 }
                 else
                 {
                     datumPoint = connectdatum.First();
                 }
                 CyPhyMLClasses.PortComposition.Connect(point, datumPoint, parent: component);
             }
         }
         catch (Exception ex)
         {
             GMEConsole.Error.WriteLine("Error during creating analysis points: " + ex.Message);
             addon.Project.AbortTransaction();
             return;
         }
         addon.Project.CommitTransaction();
     }
 }
 private void StartComponentEditAction(MetaLinkProtobuf.Edit message)
 {
     // message.topic[1] is the component AVMID
     String avmid = message.topic[1];
     StartComponentEdit(avmid);
 }
        /// <summary>
        /// The main dispatch handler for incoming messages
        /// </summary>
        /// <param name="message"></param>
        private void ProcessEditMessage(MetaLinkProtobuf.Edit message)
        {
            if (GMEConsole == null)
            {
                GMEConsole = GMEConsole.CreateFromProject(addon.Project);
            }
            // This is the first message from Creo, hide the CAD Startup Dialog
            if (StartupDialog.Visible && message.origin.Contains(CadAssemblyOrigin) &&
                message.editMode == Edit.EditMode.INTEREST && message.topic.Count == 1 &&
                message.topic[0] == LastStartedInstance.InstanceId)
            {
                ShowStartupDialog(false);
            }
            // Drop a message to the console with the acknowledgement of a previous message
            if (message.actions.Count > 0)
            {
                foreach (var action in message.actions)
                {
                    foreach (var notice in action.notices)
                    {
                        if (notice.noticeMode == Notice.NoticeMode.DONE)
                        {
                            GMEConsole.Info.WriteLine("Done response from Meta-Link: " + notice.msg);
                        }
                        else if (notice.noticeMode == Notice.NoticeMode.ACK)
                        {
                            GMEConsole.Info.WriteLine("Ack response from Meta-Link: " + notice.msg);
                        }
                        else if (notice.noticeMode == Notice.NoticeMode.WARN)
                        {
                            GMEConsole.Warning.WriteLine("Warn response from Meta-Link: " + notice.msg);
                        }
                    }
                }
            }
            if (!TestMode && message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.INTEREST, MetaLinkProtobuf.Edit.EditMode.NOTICE }))
            {
                // Start Creo in design editing mode
                if (message.notices.Count == 1 && message.notices[0].noticeMode == Notice.NoticeMode.ACK)
                {
                    SyncedComponentData cdata = GetSyncedCompDataByInstanceId(message.topic[0]);
                    if (cdata == null)
                    {
                        GMEConsole.Error.WriteLine("Fatal error: can't find component data for synced component: " + message.topic[0]);
                    }
                    else if (cdata.Type == SyncedComponentData.EditType.Design)
                    {
                        // message.topic[1] is the assembly GUID
                        string assemblyGuid = Guid.Parse(cdata.Id).ToString();

                        string exeparams = "";
                        addon.Project.BeginTransactionInNewTerr();
                        try
                        {
                            exeparams = GetStartupParams(assemblyGuid);
                        }
                        finally
                        {
                            addon.Project.AbortTransaction();
                        }

                        StartAssemblyExe(CreoOpenMode.OPEN_COMPONENT, assemblyGuid, true, exeparams);
                    }
                    else
                    {
                        Action<MetaLinkProtobuf.Edit> action;
                        if (noticeActions.TryGetValue(message.guid, out action))
                        {
                            noticeActions.Remove(message.guid);
                            action(message);
                        }
                    }
                }
            }

            // Write message to console if it's an error response
            if (message.mode.Count > 0 && message.mode.Last() == MetaLinkProtobuf.Edit.EditMode.NOTICE)
            {
                foreach (var notice in message.actions.SelectMany(a => a.notices)
                    .Where(n => n.noticeMode == Notice.NoticeMode.FAULT || n.noticeMode == Notice.NoticeMode.FAIL))
                {
                    GMEConsole.Error.WriteLine("Meta-Link error: " + notice.msg);
                }
            }

            // ignore messages from ourselves
            if (message.origin.Contains(GMEOrigin))
            {
                return;
            }

            // DISINTEREST: The user closed Creo (component)
            if (message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.DISINTEREST }))
            {
                SyncedComponentData cdata = GetSyncedCompDataByInstanceId(message.topic[0]);
                if (cdata.Type == SyncedComponentData.EditType.Component)
                {
                    String componentAVMID = cdata.Id;
                    //componentEditMessages.Remove(componentAVMID);
                    syncedComponents.Remove(componentAVMID);
                    SendDisinterest(false, cdata.InstanceId);
                    addon.Project.BeginTransactionInNewTerr();
                    try
                    {
                        var component = CyphyMetaLinkUtils.GetComponentByAvmId(addon.Project, componentAVMID);
                        if (component != null)
                        {
                            HighlightInTree(component, 0);
                        }
                    }
                    finally
                    {
                        addon.Project.AbortTransaction();
                    }
                }
                else if (cdata.Type == SyncedComponentData.EditType.Empty)
                {
                    syncedComponents.Remove(""); // CAD has been started in an empty mode
                }

                else
                {
                    Guid componentAssemblyID = Guid.Parse(cdata.Id);

                    syncedComponents.Remove(componentAssemblyID.ToString());
                    SendDisinterest(true, cdata.InstanceId);
                    addon.Project.BeginTransactionInNewTerr();
                    try
                    {
                        CyPhyML.ComponentAssembly assembly = CyphyMetaLinkUtils.GetComponentAssemblyByGuid(addon.Project, AssemblyID);
                        if (assembly != null)
                        {
                            HighlightInTree(assembly, 0);
                        }
                    }
                    finally
                    {
                        addon.Project.AbortTransaction();
                    }
                    AssemblyID = null;
                }
            }
            else
                // Create analysis point
                if (message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.POST }) &&
                    message.actions.Count >= 1 && message.actions[0].actionMode == MetaLinkProtobuf.Action.ActionMode.CREATE_ANALYSIS_POINTS)
            {
                foreach (var action in message.actions)
                {
                    ProcessAnalysisPointMessage(action.subjectID, action);
                }
            }
            else
                // Design edit message (insert/select/discard) 
                if (message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.POST }) && message.actions.Count >= 1 &&
                    (message.actions[0].actionMode == MetaLinkProtobuf.Action.ActionMode.ADD_COMPONENT_TO_CYPHY_DESIGN ||
                    message.actions[0].actionMode == MetaLinkProtobuf.Action.ActionMode.SELECT_CYPHY_COMPONENT ||
                    message.actions[0].actionMode == MetaLinkProtobuf.Action.ActionMode.REMOVE_CYPHY_DESIGN_COMPONENT))
            {
                foreach (var action in message.actions)
                {
                    if (action.actionMode == MetaLinkProtobuf.Action.ActionMode.ADD_COMPONENT_TO_CYPHY_DESIGN && action.payload != null)
                    {
                        // Add an AVM component
                        ProcessEditInsert(action.subjectID, action);
                    }
                    else if (action.actionMode == MetaLinkProtobuf.Action.ActionMode.SELECT_CYPHY_COMPONENT && action.payload != null)
                    {
                        // Select a component
                        ProcessEditSelect(action.subjectID, action);
                    }
                    else if (action.actionMode == MetaLinkProtobuf.Action.ActionMode.REMOVE_CYPHY_DESIGN_COMPONENT)
                    {
                        // Remove a component
                        ProcessEditDiscard(action.subjectID, action);
                    }
                    else
                    {
                        GMEConsole.Warning.WriteLine("Unknown action: " + message.ToString());
                    }
                }
            }
            else
                // Re-sync
                if (message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.POST }) &&
                    message.actions.Count >= 1 && message.actions[0].actionMode == MetaLinkProtobuf.Action.ActionMode.RESYNC)
            {
                ProcessResync(message.actions[0].subjectID);
            }
            else
                // Send assembly/component info to the client
                if (message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.INTEREST }))
            {
                SyncedComponentData cdata = GetSyncedCompDataByInstanceId(message.topic[0]);
                if (cdata.Type == SyncedComponentData.EditType.Component)
                {
                    addon.Project.BeginTransactionInNewTerr();
                    try
                    {
                        CyPhyML.Component avmcomp = CyphyMetaLinkUtils.FindAVMComponent(addon.Project, cdata.Id, null);

                        if (avmcomp == null)
                        {
                            throw new Exception(String.Format("Can't find AVM component to open with id {0}.", cdata.Id));
                        }

                        var outmessage = CreateComponentEditMessage(cdata.InstanceId, avmcomp, CyphyMetaLinkUtils.FindCADModelObject(avmcomp));

                        if (outmessage != null)
                        {
                            //SendInterest(null, ResyncTopic, message.topic[1]);
                            bridgeClient.SendToMetaLinkBridge(outmessage);
                        }
                        else
                        {
                            GMEConsole.Warning.WriteLine("MetaLink: don't know about component " + cdata.Id);
                        }
                        // This is a recently created component
                        if (!syncedComponents.ContainsKey(avmcomp.Attributes.AVMID))
                        {
                            SyncedComponentData syncedCompData = new SyncedComponentData()
                            {
                                Type = SyncedComponentData.EditType.Component,
                                Id = avmcomp.Attributes.AVMID
                            };
                            syncedComponents.Add(avmcomp.Attributes.AVMID, syncedCompData);
                            HighlightInTree(avmcomp, 1);
                        }
                    }
                    finally
                    {
                        addon.Project.AbortTransaction();
                    }
                }
                else
                {
                    string designId = cdata.Id;
                    string xml;
                    if (designIdToCadAssemblyXml.TryGetValue(designId, out xml))
                    {
                        addon.Project.BeginTransactionInNewTerr();
                        try
                        {
                            SendCadAssemblyXml(message.topic[0], xml, designId, false);
                            SaveCadAssemblyXml(xml, designId);
                        }
                        finally
                        {
                            addon.Project.AbortTransaction();
                        }
                    }
                    else
                    {
                        GMEConsole.Warning.WriteLine("MetaLink: unknown assembly " + designId);
                    }
                }
            }
            else
                // Request component list message from Creo
                if (message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.POST }) &&
                    message.actions.Count >= 1 && message.actions[0].actionMode == MetaLinkProtobuf.Action.ActionMode.REQUEST_COMPONENT_LIST)
            {
                addon.Project.BeginTransactionInNewTerr();
                try
                {
                    SendComponentList(message.topic[0]);
                }
                finally
                {
                    addon.Project.AbortTransaction();
                }
            }
            else
                // Update AVM Component with the information from Creo
                if (message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.POST }) &&
                    message.actions.Count == 1 && message.actions[0].actionMode == MetaLinkProtobuf.Action.ActionMode.UPDATE_CYPHY_COMPONENT &&
                    message.actions[0].alien != null && message.actions[0].alien.encodingMode == Alien.EncodingMode.XML)
            {
                string componentId = message.actions[0].subjectID;
                string component_xml = Encoding.UTF8.GetString(message.actions[0].alien.encoded);
                ProcessAVMComponentUpdate(componentId, component_xml);
            }
            else
                // Create a connector in component
                if (message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.POST }) &&
                    message.actions.Count >= 1 && message.actions[0].actionMode == MetaLinkProtobuf.Action.ActionMode.ADD_CONNECTOR_TO_COMPONENT)
            {
                string componentId = message.actions[0].subjectID;
                ProcessInsertComponentConnector(componentId, message.actions[0]);
            }
            else
                // Create new CyPhy component
                if (message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.POST }) &&
                    message.actions.Count == 1 && message.actions[0].actionMode == MetaLinkProtobuf.Action.ActionMode.CREATE_CYPHY_COMPONENT &&
                    message.actions[0].alien != null && message.actions[0].alien.encodingMode == Alien.EncodingMode.XML)
            {
                string component_xml = Encoding.UTF8.GetString(message.actions[0].alien.encoded);
                ProcessAVMComponentCreate(component_xml, message.topic[0]);
            }
            else
                // Connect component within a design
                if (message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.POST }) &&
                    message.actions.Count >= 1 && message.actions[0].actionMode == MetaLinkProtobuf.Action.ActionMode.CONNECT_COMPONENTS_CYPHY)
            {
                try
                {
                    string assemblyID = message.actions[0].payload.components[0].ComponentID;
                    string conn1 = message.actions[0].payload.components[1].ComponentID.Substring(0, message.actions[0].payload.components[1].ComponentID.IndexOf('_'));
                    string ref1 = message.actions[0].payload.components[1].ComponentID.Substring(message.actions[0].payload.components[1].ComponentID.IndexOf('_') + 1);
                    string conn2 = message.actions[0].payload.components[2].ComponentID.Substring(0, message.actions[0].payload.components[2].ComponentID.IndexOf('_'));
                    string ref2 = message.actions[0].payload.components[2].ComponentID.Substring(message.actions[0].payload.components[2].ComponentID.IndexOf('_') + 1);
                    ProcessConnect(assemblyID, conn1, ref1, conn2, ref2);
                }
                catch (Exception ex)
                {
                    GMEConsole.Warning.WriteLine("Error during processing connect message: " + ex.Message);
                }
            }
            else
            {
                GMEConsole.Warning.WriteLine("Message left unprocessed: " + message.ToString());
            }
        }
        private void ProcessEditMessage(MetaLinkProtobuf.Edit message)
        {
            if (GMEConsole == null)
            {
                GMEConsole = GMEConsole.CreateFromProject(addon.Project);
            }
            // This is the first message from Creo, hide the Startup Dialog
            if (StartupDialog.Visible && message.origin.Contains(CadAssemblyOrigin) &&
                message.editMode == Edit.EditMode.INTEREST && message.topic.Count == 2 &&
                message.topic[1] == LastStartedGuid)
            {
                ShowStartupDialog(false);
            }
            // Drop a warning message to the console if it's a suspicious response
            if (message.actions.Count > 0)
            {
                foreach (var action in message.actions)
                {
                    foreach (var notice in action.notices)
                    {
                        if (notice.noticeMode == Notice.NoticeMode.DONE)
                        {
                            GMEConsole.Info.WriteLine("Done response from Meta-Link: " + notice.msg);
                        }
                        else if (notice.noticeMode == Notice.NoticeMode.ACK)
                        {
                            GMEConsole.Info.WriteLine("Ack response from Meta-Link: " + notice.msg);
                        }
                        else if (notice.noticeMode == Notice.NoticeMode.WARN)
                        {
                            GMEConsole.Warning.WriteLine("Warn response from Meta-Link: " + notice.msg);
                        }
                    }
                }
            }
            if (message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.INTEREST, MetaLinkProtobuf.Edit.EditMode.NOTICE }))
            {

                // Start Creo in design editing mode
                if (message.topic.Count == 2 && message.topic[0] == CadAssemblyTopic
                    && message.notices.Count == 1 && message.notices[0].noticeMode == Notice.NoticeMode.ACK)
                {
                    // message.topic[1] is the assembly GUID
                    string assemblyGuid = Guid.Parse(message.topic[1]).ToString();

                    string exeparams = "";
                    addon.Project.BeginTransactionInNewTerr();
                    try
                    {
                        exeparams = GetStartupParams(assemblyGuid);
                    }
                    finally
                    {
                        addon.Project.AbortTransaction();
                    }

                    StartAssemblyExe(CreoOpenMode.OPEN_COMPONENT, assemblyGuid, true, exeparams);
                }

                // Start Creo in AVM component editing mode
                if (message.topic.Count >= 2 && message.topic[0] == ComponentUpdateTopic
                    && message.notices.Count == 1 && message.notices[0].noticeMode == Notice.NoticeMode.ACK)
                {
                    Action<MetaLinkProtobuf.Edit> action;
                    if (noticeActions.TryGetValue(message.guid, out action))
                    {
                        noticeActions.Remove(message.guid);
                        action(message);
                    }
                }
                
            }

            if (message.mode.Count > 0 && message.mode.Last() == MetaLinkProtobuf.Edit.EditMode.NOTICE)
            {
                foreach (var notice in message.actions.SelectMany(a => a.notices)
                    .Where(n => n.noticeMode == Notice.NoticeMode.FAULT || n.noticeMode == Notice.NoticeMode.FAIL ||
                            n.noticeMode == Notice.NoticeMode.REJECT))
                {
                    GMEConsole.Error.WriteLine("Meta-Link error: " + notice.msg);
                }
            }


            if (message.origin.Contains(GMEOrigin)) // ignore messages from ourselves
                return;

            // DISINTEREST: The user closed Creo (component)
            if (message.topic.Count == 2 && (message.topic[0] == ComponentUpdateTopic || message.topic[0] == CadPassiveTopic) &&
                message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.DISINTEREST }))
            {
                if (message.topic[0] == ComponentUpdateTopic)
                {
                    String componentAVMID = message.topic[1];
                    //componentEditMessages.Remove(componentAVMID);
                    syncedComponents.Remove(componentAVMID);
                    SendDisinterest(ComponentUpdateTopic, componentAVMID);
                    addon.Project.BeginTransactionInNewTerr();
                    try
                    {
                        var component = CyphyMetaLinkUtils.GetComponentByAvmId(addon.Project, componentAVMID);
                        if (component != null)
                        {
                            HighlightInTree(component, 0);
                        }
                    }
                    finally
                    {
                        addon.Project.AbortTransaction();
                    }
                }
                else
                {
                    syncedComponents.Remove(""); // CAD has been started in an empty mode
                }
            }

            // DISINTEREST: The user closed Creo (design)
            if (message.topic.Count == 2 && message.topic[0] == CadAssemblyTopic &&
                message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.DISINTEREST }))
            {
                Guid componentAssemblyID = Guid.Parse(message.topic[1]);
                /*try{
                    Directory.Delete(syncedComponents[componentAssemblyID.ToString()].WorkingDir);
                } catch (Exception e)
                {
                    GMEConsole.Warning.WriteLine("Unable to delete working directory: " + e.Message);
                }*/
                syncedComponents.Remove(componentAssemblyID.ToString());
                SendDisinterest(CadAssemblyTopic, message.topic[1]);
                addon.Project.BeginTransactionInNewTerr();
                try
                {
                    CyPhyML.ComponentAssembly assembly = CyphyMetaLinkUtils.GetComponentAssemblyByGuid(addon.Project, AssemblyID);
                    if (assembly != null)
                    {
                        HighlightInTree(assembly, 0);
                    }
                }
                finally
                {
                    addon.Project.AbortTransaction();
                }
                AssemblyID = null;
            }

            if (message.topic.Count == 2 && message.topic[0] == ComponentAnalysisPointTopic &&
                message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.POST }))
            {
                foreach (var action in message.actions)
                {
                    ProcessAnalysisPointMessage(message.topic[1], action);
                }
            }                
                

            // Design edit message (insert/select/discard) 
            if (message.topic.Count == 2 && message.topic[0] == CadAssemblyTopic &&
                message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.POST }))
            {
                foreach (var action in message.actions)
                {
                    if (action.actionMode == MetaLinkProtobuf.Action.ActionMode.INSERT && action.payload != null)
                    {
                        // Add an AVM component
                        ProcessEditInsert(message.topic[1], action);
                    }
                    if (action.actionMode == MetaLinkProtobuf.Action.ActionMode.SELECT && action.payload != null)
                    {
                        // Select a component ref
                        ProcessEditSelect(message.topic[1], action);
                    }
                    if (action.actionMode == MetaLinkProtobuf.Action.ActionMode.DISCARD)
                    {
                        // Remove a component ref
                        ProcessEditDiscard(message.topic[1], action);
                    }
                }
            }

            // Re-sync
            if (message.topic.Count == 2 && message.topic[0] == ResyncTopic &&
                message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.POST }))
            {
                ProcessResync(message.topic[1]);
            }
            

            if (message.topic.Count == 2 && message.topic[0] == CadAssemblyTopic &&
                message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.INTEREST }))
            {
                string designId = message.topic[1];
                string xml;
                if (designIdToCadAssemblyXml.TryGetValue(designId, out xml))
                {
                    addon.Project.BeginTransactionInNewTerr();
                    try
                    {
                        SendCadAssemblyXml(xml, designId, false);
                        SaveCadAssemblyXml(xml, designId);
                    }
                    finally
                    {
                        addon.Project.AbortTransaction();
                    }
                }
                else
                {
                    GMEConsole.Warning.WriteLine("MetaLink: unknown assembly " + designId);
                }
            }

            // Request component list message from Creo
            if (message.topic.Count > 0 && message.topic[0] == ComponentManifestTopic &&
                message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.INTEREST }))
            {
                addon.Project.BeginTransactionInNewTerr();
                try
                {
                    SendComponentManifest();
                }
                finally
                {
                    addon.Project.AbortTransaction();
                }
            }

            // Update AVM Component with the information from Creo
            if (message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.POST }) &&
                message.topic.Count >= 2 && message.topic[0] == ComponentUpdateTopic && message.actions.Count == 1 &&
                message.actions[0].alien != null && message.actions[0].alien.encodingMode == Alien.EncodingMode.XML)
            {
                string componentId = message.topic[1];
                string component_xml = Encoding.UTF8.GetString(message.actions[0].alien.encoded);
                ProcessAVMComponentUpdate(componentId, component_xml);
            }

            // Some type of AVM component update (INSERT, DISCARD, etc.)
            if (message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.POST }) &&
                message.topic.Count >= 2 && message.topic[0] == ComponentUpdateTopic && message.actions.Count >= 1)
            {
                string componentId = message.topic[1];
                foreach (var action in message.actions)
                {
                    if (action.actionMode == MetaLinkProtobuf.Action.ActionMode.INSERT && action.payload != null)
                    {
                        ProcessAVMComponentInsert(message.topic[1], action);
                    }
                }
                
            }
            // Create new AVM component
            if (message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.POST }) &&
                message.topic.Count <= 2 && message.topic[0] == ComponentCreateTopic && message.actions.Count == 1 &&
                message.actions[0].alien != null && message.actions[0].alien.encodingMode == Alien.EncodingMode.XML)
            {
                string component_xml = Encoding.UTF8.GetString(message.actions[0].alien.encoded);
                ProcessAVMComponentCreate(component_xml, message.topic.Count>1?message.topic[1]:null);
            }

            // Connect component within a design
            if (message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.POST }) &&
                message.topic.Count >= 1 && message.topic[0] == ConnectTopic)
            {
                try
                {
                    string conn1 = message.actions[0].payload.components[1].ComponentID.Substring(0, message.actions[0].payload.components[1].ComponentID.IndexOf('_'));
                    string ref1 = message.actions[0].payload.components[1].ComponentID.Substring(message.actions[0].payload.components[1].ComponentID.IndexOf('_')+1);
                    string conn2 = message.actions[0].payload.components[2].ComponentID.Substring(0, message.actions[0].payload.components[2].ComponentID.IndexOf('_'));
                    string ref2 = message.actions[0].payload.components[2].ComponentID.Substring(message.actions[0].payload.components[2].ComponentID.IndexOf('_') + 1);
                    ProcessConnect(message.actions[0].payload.components[0].ComponentID, conn1, ref1, conn2, ref2);
                }
                catch (Exception ex)
                {
                    GMEConsole.Warning.WriteLine("Error during processing " + ConnectTopic + " message: " + ex.Message);
                }
            }

            // Send AVM component update to Creo
            if (message.mode.SequenceEqual(new Edit.EditMode[] { Edit.EditMode.INTEREST }) &&
                message.topic.Count >= 2 && message.topic[0] == ComponentUpdateTopic)
            {
                addon.Project.BeginTransactionInNewTerr();
                try
                {
                    CyPhyML.Component avmcomp = CyphyMetaLinkUtils.FindAVMComponent(addon.Project, message.topic[1], null);

                    if (avmcomp == null)
                        throw new Exception(String.Format("Can't find AVM component to open with id {0}.", message.topic[1]));

                    var outmessage = CreateComponentEditMessage(avmcomp, CyphyMetaLinkUtils.FindCADModelObject(avmcomp));

                    if (outmessage != null)
                    {
                        SendInterest(null, ResyncTopic, message.topic[1]);
                        bridgeClient.SendToMetaLinkBridge(outmessage);
                    }
                    else
                    {
                        GMEConsole.Warning.WriteLine("MetaLink: don't know about component " + message.topic[1]);
                    }
                    // This is a recently created component
                    if (!syncedComponents.ContainsKey(avmcomp.Attributes.AVMID))
                    {
                        SyncedComponentData syncedCompData = new SyncedComponentData()
                        {
                            Type = SyncedComponentData.EditType.Component
                        };
                        syncedComponents.Add(avmcomp.Attributes.AVMID, syncedCompData);
                        HighlightInTree(avmcomp, 1);
                    }
                }
                finally
                {
                    addon.Project.AbortTransaction();
                }
            }
        }
 public void EditMessageReceived(MetaLinkProtobuf.Edit message)
 {
     queuedMessages.Enqueue(message);
     SyncControl.BeginInvoke((System.Action)delegate
     {
         if (addon != null)
         {
             ProcessQueuedEditMessages();
         }
     });
 }
 private void StartComponentEditAction(MetaLinkProtobuf.Edit message)
 {
     // message.topic[1] is the component AVMID
     String avmid = GetSyncedCompDataByInstanceId(message.topic[0]).Id;
     StartComponentEdit(avmid);
 }
 public void EditMessageReceived(MetaLinkProtobuf.Edit message)
 {
     queuedMessages.Enqueue(message);
     SyncControl.BeginInvoke((System.Action)delegate
     {
         if (addon != null)
         {
             /*if ((addon.Project.ProjectStatus & 8) != 0) // in tx
             {
                 GMEConsole.Warning.WriteLine("Message received during transaction, ignoring.");
                 // In GlobalEvent, we will post a message to process the queue
             }
             else
             {*/
                 ProcessQueuedEditMessages();
             //}
         }
     });
 }
예제 #13
0
        public bool SendToMetaLinkBridge(MetaLinkProtobuf.Edit message)
        {
            bool status = true;
            if (ConnectionEnabled)
            {
                _socketQueue.enQueue(message);
            }
            else
                status = false;

            return status; // FIXME: doesn't really mean anything, since the send thread could fail. Does the consumer want a callback?
        }
예제 #14
0
 public void enQueue(MetaLinkProtobuf.Edit message)
 {
     _messageQueue.Add(message);
 }
예제 #15
0
        private void sendMessage(MetaLinkProtobuf.Edit message)
        {
            MemoryStream messageMemoryStream = new MemoryStream();
            ProtoBuf.Serializer.Serialize(messageMemoryStream, message);
            byte[] payload = messageMemoryStream.GetBuffer();
            int payloadLength = (int)messageMemoryStream.Length;

            MemoryStream frameMemoryStream = new MemoryStream();

            encodeInteger(frameMemoryStream, 0xDEADBEEF);
            encodeInteger(frameMemoryStream, (int)messageMemoryStream.Length);
            encodeInteger(frameMemoryStream, 0);

            byte[] payloadHash = getCrc32(payload, payloadLength);
            frameMemoryStream.Write(payloadHash, 0, 4);

            byte[] frame = frameMemoryStream.GetBuffer();
            int frameLength = (int)frameMemoryStream.Length;
            byte[] frameHash = getCrc32(frame, frameLength);
            frameMemoryStream.Write(frameHash, 0, 4);

            frameMemoryStream.Write(payload, 0, payloadLength);
            frameMemoryStream.Write(payloadHash, 0, 4);

            _networkStream.Write(frameMemoryStream.GetBuffer(), 0, (int)frameMemoryStream.Length);
            _networkStream.Flush();
        }
 private void AddSearchPathToEnvironment(CyPhyML.Component component, MetaLinkProtobuf.Environment env)
 {
     string path = Path.GetDirectoryName(GetCadModelPath(component));
     if (path == null)
     {
         // not everything needs a CAD model
         // GMEConsole.Warning.WriteLine(String.Format("MetaLink warning: component '{0}' has no CAD model", component.Name));
     }
     else
     {
         env.value.Add(path);
     }
 }