public void CustomLogic(ref string[] scene, ref YamlDocument yamlDocument, ScriptMapping scriptMapping)
        {
            // Get all values
            YamlNode yamlNodes = yamlDocument.RootNode.GetChildren()["MonoBehaviour"];

            // Get the value we wish to change, this is the originalValue and has not been changed in the yaml document
            // That's why we need to use the original name to transform the data
            YamlNode originalValue = yamlNodes["testQuaternion"];
            int      line          = originalValue.Start.Line - 1;

            // Transform the data
            Vector3 newValue = new Quaternion(
                float.Parse(originalValue["x"].ToString()),
                float.Parse(originalValue["y"].ToString()),
                float.Parse(originalValue["z"].ToString()),
                float.Parse(originalValue["w"].ToString())
                ).eulerAngles;

            // Make the value we want to set
            string valueString = "{ x : " + newValue.x + ", y : " + newValue.y + ", z : " + newValue.z + " }";

            // Get the key that is in the newest version of the scene (this is the changed value so testQuaternion2)
            // When setting values be careful with indenting as yaml uses indents for structure
            // Indents can be set by adding "\t" and new lines can be added by using "\r\n"
            string original = scene[line].Substring(0, scene[line].IndexOf(':'));

            // Replace it in the original file
            scene[line] = original + ": " + valueString;
        }
示例#2
0
        public void MultirowScriptMappingWorksCorrectly()
        {
            ScriptMapping script = new ScriptMapping("return Get-Date ([datetime]::ParseExact($inputValues.WeirdDate,'ddMMyyyy_HHmmss',$null)) -Format 'yyyy-mm-dd'");
            Dictionary <string, object> inputRow1 = new Dictionary <string, object>();

            inputRow1.Add("WeirdDate", "24122014_022257");
            string expected1 = "2014-22-24";
            string actual1   = (string)script.GetValue(inputRow1);

            Dictionary <string, object> inputRow2 = new Dictionary <string, object>();

            inputRow2.Add("WeirdDate", "24122017_022257");
            string expected2 = "2017-22-24";
            string actual2   = (string)script.GetValue(inputRow2);

            Dictionary <string, object> inputRow3 = new Dictionary <string, object>();

            inputRow3.Add("WeirdDate", "24122020_022257");
            string expected3 = "2020-22-24";
            string actual3   = (string)script.GetValue(inputRow3);

            CollectionAssert.AreEqual(
                new string[] { expected1, expected2, expected3 },
                new string[] { actual1, actual2, actual3 },
                "Wrong values parsed out for multi row script mapping"
                );
        }
示例#3
0
        /// <summary>
        /// Merge two lists of scriptMappings to one using the oldClassModel.Name
        /// </summary>
        /// <param name="originalScriptMappings"></param>
        /// <param name="scriptMappingsToMerge"></param>
        /// <returns></returns>
        /// <exception cref="NullReferenceException"></exception>
        public static List <ScriptMapping> Merge(this List <ScriptMapping> originalScriptMappings,
                                                 List <ScriptMapping> scriptMappingsToMerge)
        {
            if (originalScriptMappings == null || scriptMappingsToMerge == null)
            {
                throw new NullReferenceException("Could not merge scriptMappings for null scriptMappings list");
            }

            // Merge the MergeWindow changed scriptMappings with the originalScriptMappings
            for (var i = 0; i < originalScriptMappings.Count; i++)
            {
                ScriptMapping originalScriptMapping = originalScriptMappings[i];
                ScriptMapping changedScriptMapping  = scriptMappingsToMerge.FirstOrDefault(script =>
                                                                                           script.oldClassModel.FullName == originalScriptMapping.oldClassModel.FullName);
                if (changedScriptMapping != null)
                {
                    originalScriptMappings[i] = changedScriptMapping;
                }
            }

            foreach (ScriptMapping scriptmapping in scriptMappingsToMerge)
            {
                if (!originalScriptMappings.Exists(script =>
                                                   script.oldClassModel.FullName == scriptmapping.oldClassModel.FullName))
                {
                    originalScriptMappings.Add(scriptmapping);
                }
            }

            return(originalScriptMappings);
        }
示例#4
0
        private string[] handleSequenceNode(ref string[] scene, MergeNode currentMergeNode, List <ScriptMapping>
                                            scriptMappings, KeyValuePair <YamlNode, YamlNode> yamlNode)
        {
            int line = yamlNode.Key.Start.Line - 1;

            scene[line] = scene[line].ReplaceFirst(currentMergeNode.OriginalValue, currentMergeNode.NameToExportTo);
            string type = currentMergeNode.Type;

            ScriptMapping scriptMapping =
                scriptMappings.FirstOrDefault(script => script.oldClassModel.Name == type);

            if (scriptMapping == null)
            {
                Debug.Log("Could not find scriptMapping for MergeNode, Type : " + currentMergeNode.Type +
                          " originalValue : " +
                          currentMergeNode.OriginalValue);
                return(scene);
            }

            var items = yamlNode.Value.GetItems();

            if (items == null || items.Count == 0)
            {
                return(scene);
            }

            foreach (YamlNode item in items)
            {
                scene = recursiveReplaceField(ref scene, scriptMapping.MergeNodes, item, scriptMappings);
            }

            return(scene);
        }
示例#5
0
        public static void AddScriptMapping(this IServiceCollection coll, string toPath, Func <IScriptModelMappingService, string> f)
        {
            var mapp = new ScriptMapping(f)
            {
                FilePath = toPath
            };

            ScriptMapSettings.Add(mapp);
        }
示例#6
0
        public void ComplexScriptMappingWorksCorrectly()
        {
            ScriptMapping script = new ScriptMapping("return Get-Date ([datetime]::ParseExact($inputValues.WeirdDate,'ddMMyyyy_HHmmss',$null)) -Format 'yyyy-mm-dd'");
            Dictionary <string, object> inputRow = new Dictionary <string, object>();

            inputRow.Add("WeirdDate", "24122014_022257");
            string expected = "2014-22-24";
            object actual   = script.GetValue(inputRow);

            Assert.AreEqual(expected, actual, "Complex script mapping work correctly");
        }
示例#7
0
        public void ScriptMappingWorksCorrectly()
        {
            ScriptMapping script = new ScriptMapping("return \"hello \" + $inputValues.A");
            Dictionary <string, object> inputRow = new Dictionary <string, object>();

            inputRow.Add("A", "C");
            object expected = "hello C";
            object actual   = script.GetValue(inputRow);

            Assert.AreEqual(expected, actual, "Script mapping work correctly");
        }
示例#8
0
        /// <summary>
        /// Checks if there is some custom logic that can be called.
        /// And calls that logic
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="document"></param>
        /// <param name="scriptMapping"></param>
        /// <returns>True when it handles logic, else false and it still needs to be handled</returns>
        private bool CheckCustomLogic(ref string[] scene,
                                      YamlDocument document, ScriptMapping scriptMapping)
        {
            if (!Constants.Instance.CustomLogicMapping.ContainsKey(scriptMapping.newClassModel.FullName))
            {
                return(false);
            }

            ICustomMappingLogic customLogic =
                Constants.Instance.CustomLogicMapping[scriptMapping.newClassModel.FullName];

            customLogic.CustomLogic(ref scene, ref document, scriptMapping);
            return(true);
        }
示例#9
0
            public ScriptMappingWrapper(ScriptMapping scriptMapping)
            {
                ScriptMapping        = scriptMapping;
                FieldSelectionStates = new bool[scriptMapping.MergeNodes.Count];

                for (var i = 0; i < scriptMapping.MergeNodes.Count; i++)
                {
                    MergeNode mergeNode = scriptMapping.MergeNodes[i];
                    FieldSelectionStates[i] = mergeNode.OriginalValue != mergeNode.NameToExportTo;
                }

                OptionSelections = new int[scriptMapping.MergeNodes.Count];
                for (int i = 0; i < OptionSelections.Length; i++)
                {
                    OptionSelections[i] = 0;
                }
            }
示例#10
0
        private void ConvertScene(string scenePath, ref string[] scene, List <ScriptMapping> scriptMappings,
                                  YamlStream yamlStream)
        {
            List <YamlDocument> yamlDocuments =
                yamlStream.Documents.Where(document => document.GetName() == "MonoBehaviour").ToList();

            foreach (YamlDocument document in yamlDocuments)
            {
                try
                {
                    YamlNode script = document.RootNode.GetChildren()["MonoBehaviour"]; //todo : duplicate code, fix

                    string fileID = (string)script["m_Script"]["fileID"];
                    string guid   = (string)script["m_Script"]["guid"];

                    ScriptMapping scriptMappingType =
                        scriptMappings.FirstOrDefault(node =>
                                                      node.newClassModel.Guid == guid && node.newClassModel.FileID == fileID);

                    if (scriptMappingType != null)
                    {
                        if (scriptMappingType.HasBeenMapped == ScriptMapping.MappedState.NotMapped ||
                            scriptMappingType.HasBeenMapped == ScriptMapping.MappedState.Approved)
                        {
                            scene = recursiveReplaceField(ref scene, scriptMappingType.MergeNodes, script,
                                                          scriptMappings);
                        }

                        CheckCustomLogic(ref scene, document, scriptMappingType);
                    }
                    else
                    {
                        Debug.Log("Script found that has no mapping (No members will be replaced) in scene : " +
                                  scenePath +
                                  ", Node: " +
                                  document.RootNode.ToString());
                    }
                }
                catch (Exception e)
                {
                    Debug.LogError("Could not convert scene in the FieldMappingController scene: " + scenePath +
                                   "\r\nException:" + e);
                }
            }
        }
        /// <summary>
        /// Maps all scriptMappings for all variables and children of the type of the variable
        /// Finds the scriptMapping that you need and otherwise creates it.
        /// </summary>
        /// <param name="newIDs">The IDs of the new project</param>
        /// <param name="scriptMappings">The existing scriptMappings that will be looked in and added to</param>
        /// <param name="oldClassModel">Current class data of the old project as this maps to the scene file</param>
        /// <returns></returns>
        /// <exception cref="NullReferenceException"></exception>
        public ScriptMapping FindMappingRecursively(List <ClassModel> newIDs,
                                                    ref List <ScriptMapping> scriptMappings, ClassModel oldClassModel)
        {
            // Can't look for something if we don't know what we're looking for
            if (oldClassModel == null)
            {
                throw new NullReferenceException("No old classData found");
            }

            ScriptMapping existingScriptMapping = scriptMappings.FirstOrDefault(
                script => script.oldClassModel.FullName == oldClassModel.FullName
                );

            ClassModel replacementClassModel = existingScriptMapping?.newClassModel;

            if (replacementClassModel == null && oldClassModel.Fields != null)
            {
                replacementClassModel = FindNewID(newIDs, oldClassModel);
                if (replacementClassModel == null)
                {
                    return(null);
                }
            }
            else if (replacementClassModel != null)
            {
                return(existingScriptMapping);
            }
            else
            {
                return(null);
            }

            if (existingScriptMapping != null)
            {
                return(existingScriptMapping);
            }

            existingScriptMapping = new ScriptMapping
            {
                oldClassModel = oldClassModel,
                newClassModel = replacementClassModel
            };

            MappedState hasBeenMapped = existingScriptMapping.CheckHasBeenMapped();

            switch (hasBeenMapped)
            {
            case MappedState.NotMapped:
                existingScriptMapping.GenerateMappingNode();
                break;

            case MappedState.Ignored:
                return(null);
            }

            scriptMappings.Add(existingScriptMapping);

            //If it doesn't exist then create it
            if (oldClassModel.Fields != null && oldClassModel.Fields.Length != 0)
            {
                foreach (FieldModel field in oldClassModel.Fields)
                {
                    // Check if the type is null as this would cause so errors in the mapping
                    if (field.Type == null)
                    {
                        throw new NullReferenceException("type of field is null for some reason");
                    }

                    FindMappingRecursively(newIDs, ref scriptMappings, field.Type);
                }
            }

            return(existingScriptMapping);
        }
        /// <summary>
        /// Replaces the GUID and fileID, matching the oldIDs with the currentIDs
        /// </summary>
        /// <param name="linesToChange"></param>
        /// <param name="oldIDs">List of GUIDs and FileID for all classes in the previous project.</param>
        /// <param name="newIDs">List of GUIDs and FileID for all currently in the project classes.</param>
        /// <param name="scriptMappings"></param>
        /// <returns></returns>
        private string[] MigrateGUIDsAndFileIDs(string fileToChange, string[] linesToChange, List <ClassModel> oldIDs,
                                                List <ClassModel> newIDs,
                                                ref List <ScriptMapping> scriptMappings)
        {
            string sceneContent = string.Join("\r\n", linesToChange.PrepareSceneForYaml());

            YamlStream yamlStream       = new YamlStream();
            var        tempStringReader = new StringReader(sceneContent);

            yamlStream.Load(tempStringReader);
            tempStringReader.Close();
            IEnumerable <YamlDocument> yamlDocuments =
                yamlStream.Documents.Where(document => document.GetName() == "MonoBehaviour");

            foreach (YamlDocument document in yamlDocuments)
            {
                try
                {
                    YamlNode monoBehaviour = document.RootNode.GetChildren()["MonoBehaviour"];
                    YamlNode oldFileIdNode = monoBehaviour["m_Script"]["fileID"];
                    YamlNode oldGuidNode   = monoBehaviour["m_Script"]["guid"];

                    string oldFileId = oldFileIdNode.ToString();
                    string oldGuid   = oldGuidNode.ToString();

                    ClassModel oldClassModel =
                        oldIDs.FirstOrDefault(data =>
                                              data.Guid == oldGuid && data.FileID == oldFileId);
                    if (oldClassModel == null)
                    {
                        Debug.LogWarning("Could not find class for script with type, not migrating guid : " + oldGuid +
                                         " oldFileID : " + oldFileId);
                        continue;
                    }

                    ScriptMapping
                        mapping = FindMappingRecursively(newIDs, ref scriptMappings,
                                                         oldClassModel);
                    if (mapping == null)
                    {
                        Debug.LogError("mapping is null for " + oldClassModel.FullName);
                        continue;
                    }

                    ClassModel realNewClassModel =
                        newIDs.FirstOrDefault(model => model.FullName == mapping.newClassModel?.FullName);
                    if (realNewClassModel == null)
                    {
//                    Debug.LogError("mapping is null for " + oldClassModel.FullName + " could not find new guid.");
                        throw new NullReferenceException("mapping is null for " + oldClassModel.FullName +
                                                         " could not find new guid.");
                    }

                    int line = oldFileIdNode.Start.Line - 1;
                    if (!string.IsNullOrEmpty(realNewClassModel.Guid))
                    {
                        // Replace the Guid
                        linesToChange[line] = linesToChange[line].ReplaceFirst(oldGuid, realNewClassModel.Guid);
                    }
                    else
                    {
                        Debug.Log("Found empty guid in a scene! Will not replace");
                        continue;
                    }

                    if (!String.IsNullOrEmpty(oldFileId))
                    {
                        linesToChange[line] = linesToChange[line].ReplaceFirst(oldFileId, realNewClassModel.FileID);
                    }
                }
                catch (Exception e)
                {
                    Debug.LogError("Could not migrate guid and fileID in file: " + fileToChange + "\r\n node: " +
                                   document + "\r\nException" + e);
                }
            }

            return(linesToChange);
        }
示例#13
0
        private void ConvertPrefabsDataInScene(ref string[] scene, string oldRootPath, YamlStream yamlStream,
                                               List <ScriptMapping> scriptMappings)
        {
            // Copy prefabs
            List <YamlDocument> yamlPrefabs =
                yamlStream.Documents.Where(document => document.GetName() == "PrefabInstance").ToList();

            List <PrefabModel> oldPrefabs = prefabController.ExportPrefabs(oldRootPath);

            foreach (YamlDocument prefabInstance in yamlPrefabs)
            {
                //Get the prefab file we're working with
                string      prefabGuid  = (string)prefabInstance.RootNode["PrefabInstance"]["m_SourcePrefab"]["guid"];
                PrefabModel prefabModel = oldPrefabs.FirstOrDefault(prefabFile => prefabFile.Guid == prefabGuid);
                if (prefabModel == null || string.IsNullOrEmpty(prefabModel.Path))
                {
                    Debug.LogWarning(
                        "Found reference to prefab, but could not find the prefab. Might be a model file, not migrating. Prefab guid: " +
                        prefabGuid);
                    continue;
                }

                //Load in the prefab file
                YamlStream   prefabStream     = new YamlStream();
                string[]     lines            = File.ReadAllLines(prefabModel.Path).PrepareSceneForYaml();
                StringReader tempStringReader = new StringReader(string.Join("\r\n", lines));
                prefabStream.Load(tempStringReader);
                tempStringReader.Close();


                //Get the modifications that have been done
                YamlSequenceNode modifications =
                    (YamlSequenceNode)prefabInstance.RootNode["PrefabInstance"]["m_Modification"]["m_Modifications"];

                //change the modifications
                foreach (YamlNode modification in modifications)
                {
                    YamlNode target       = modification["target"];
                    string   fileID       = (string)target["fileID"];
                    string   propertyPath = (string)modification["propertyPath"];

                    YamlDocument scriptReference =
                        prefabStream.Documents.FirstOrDefault(document =>
                                                              document.RootNode.Anchor == fileID);
                    if (scriptReference == null)
                    {
//                        // handle nested prefab
//
//                        int FileID_of_nested_PrefabInstance = 0;
//                        int FileID_of_object_in_nested_Prefab = 0;
//                        var a = (FileID_of_nested_PrefabInstance ^ FileID_of_object_in_nested_Prefab) & 0x7fffffffffffffff;


                        Debug.LogError(
                            "Nested prefab detected! Can not migrate fields in the scene. If there are any field name changes these will not be migrated. Could not find reference to script in file! Currently nested prefabs are not supported.  fileID : " +
                            fileID);
                        continue;
                    }

                    if (scriptReference.GetName() != "MonoBehaviour")
                    {
                        continue;
                    }

                    YamlNode IDs = scriptReference.RootNode["MonoBehaviour"]["m_Script"];

                    string scriptGuid   = (string)IDs["guid"];
                    string scriptFileID = (string)IDs["fileID"];

                    ScriptMapping scriptMappingType =
                        scriptMappings.FirstOrDefault(node =>
                                                      node.oldClassModel.Guid == scriptGuid && node.oldClassModel.FileID == scriptFileID);
                    if (scriptMappingType == null)
                    {
//                        Debug.Log("Could not find mapping for guid: " + scriptGuid + " fileID: " + scriptFileID);
                        continue;
                    }

                    string[]         properties        = propertyPath.Split('.');
                    List <MergeNode> currentMergeNodes = scriptMappingType.MergeNodes;

                    for (var i = 0; i < properties.Length; i++)
                    {
                        string property = properties[i];
                        if (property == "Array" && properties.Length > i + 1 && properties[i + 1].StartsWith("data["))
                        {
                            // this is a list or array and can be skipped;
                            i++;
                            continue;
                        }


                        MergeNode currentMergeNode =
                            currentMergeNodes.FirstOrDefault(node => node.OriginalValue == property);
                        if (currentMergeNode == null)
                        {
                            Debug.Log("Could not find mergeNode for property: " + property);
                            continue;
                        }

                        properties[i] = currentMergeNode.NameToExportTo;

                        currentMergeNodes =
                            scriptMappings
                            .FirstOrDefault(script => script.oldClassModel.FullName == currentMergeNode.Type)
                            ?.MergeNodes;
                    }

                    int line = modification["propertyPath"].Start.Line - 1;
                    scene[line] = scene[line].ReplaceFirst(propertyPath, string.Join(".", properties));
                }
            }
        }
示例#14
0
        /// <summary>
        /// Combine multiple mappings to one
        /// </summary>
        /// <param name="allScriptMappings">A dictionary where the Key is the version and the Value is a list of the scriptMappings</param>
        /// <param name="oldVersion"></param>
        /// <param name="newVersion"></param>
        /// <returns></returns>
        public List <ScriptMapping> CombineMappings(Dictionary <string, List <ScriptMapping> > allScriptMappings,
                                                    string oldVersion, string newVersion)

        {
            // ReSharper disable once SwitchStatementMissingSomeCases
            switch (allScriptMappings.Count)
            {
            case 0:
                Debug.LogError("No mappings found, user will have to create the mappings when necessary..");
                return(new List <ScriptMapping>());

            case 1:
                Debug.LogWarning("No Mappings combined, only a single mapping available.");
                return(allScriptMappings.First().Value);
            }

            List <string> keysToRemove = new List <string>();

            foreach (var version in allScriptMappings)
            {
                if (IsInsideVersions(version.Key, oldVersion, newVersion))
                {
                    continue;
                }

                keysToRemove.Add(version.Key);
            }

            foreach (string key in keysToRemove)
            {
                allScriptMappings.Remove(key);
            }

            KeyValuePair <string, List <ScriptMapping> >[] orderedList = allScriptMappings
                                                                         .ToList()
                                                                         .OrderBy(pair => pair.Key).ToArray();
            List <List <ScriptMapping> > sortedScriptMappings = orderedList.Select(pair => pair.Value).ToList();

            var combinedScriptMapping = sortedScriptMappings[0];


            for (var i = 1; i < sortedScriptMappings.Count; i++)
            {
                List <ScriptMapping> updatedMapping      = sortedScriptMappings[i];
                List <ScriptMapping> scriptMappingsToAdd = new List <ScriptMapping>();
                foreach (ScriptMapping newMapping in updatedMapping)
                {
                    ScriptMapping oldMapping = combinedScriptMapping.FirstOrDefault(
                        old => old.newClassModel.FullName == newMapping.oldClassModel.FullName);
                    if (oldMapping == null)
                    {
                        scriptMappingsToAdd.Add(newMapping);
                        continue;
                    }

                    oldMapping.MergeNodes    = CombineMergeNodes(oldMapping.MergeNodes, newMapping.MergeNodes);
                    oldMapping.newClassModel = newMapping.newClassModel;
                }

                combinedScriptMapping.AddRange(scriptMappingsToAdd);
            }

            return(combinedScriptMapping);
        }