Пример #1
0
        private void GenerateCommonParts(string scenesPath)
        {
            if (commonParts.Count <= 0)
            {
                return;
            }
            Action <ParsedNode, List <ParsedNode> > UniteMarkers = (dest, source) => {
                var markersUnion = new Dictionary <string, int>();
                foreach (var n in source)
                {
                    foreach (var marker in n.Markers)
                    {
                        if (!markersUnion.ContainsKey(marker))
                        {
                            markersUnion.Add(marker, 0);
                        }
                        markersUnion[marker]++;
                    }
                }
                dest.Markers.Clear();
                foreach (var mkv in markersUnion)
                {
                    if (mkv.Value == source.Count)
                    {
                        dest.Markers.Add(mkv.Key);
                    }
                }
            };
            var codeHeader = $"using Lime;\n namespace {(GetBundleNamespace(mainBundleName))}.Common\n{{\n" +
                             $"<%GEN%>\n" +
                             $"}}\n";
            var commonDirectory = $"{scenesPath}/Common";

            RetryUntilSuccessCreateDirectory(commonDirectory);
            foreach (var kv in commonParts)
            {
                var root = new ParsedFramesTree {
                    ClassName  = kv.Key,
                    ParsedNode = new ParsedNode(kv.Value.First().ParsedNode),
                };
                UniteMarkers(root.ParsedNode, kv.Value.Select(j => j.ParsedNode).ToList());
                var queue = new Queue <List <ParsedFramesTree> >();
                var sync  = new Queue <ParsedFramesTree>();
                queue.Enqueue(kv.Value);
                sync.Enqueue(root);
                while (queue.Count != 0)
                {
                    var s         = queue.Dequeue();
                    var nextRoot  = sync.Dequeue();
                    var treeUnion = new Dictionary <string, List <ParsedFramesTree> >();
                    var leafUnion = new Dictionary <string, List <ParsedNode> >();
                    foreach (var ft in s)
                    {
                        foreach (var leafNode in ft.ParsedNodes)
                        {
                            var k = leafNode.Name + GetFullTypeOf(leafNode);
                            if (!leafUnion.ContainsKey(k))
                            {
                                leafUnion.Add(k, new List <ParsedNode>());
                            }
                            leafUnion[k].Add(leafNode);
                        }
                        foreach (var treeNode in ft.InnerClasses)
                        {
                            var k = treeNode.Name + GetFullTypeOf(treeNode);
                            if (!treeUnion.ContainsKey(k))
                            {
                                treeUnion.Add(k, new List <ParsedFramesTree>());
                            }
                            treeUnion[k].Add(treeNode);
                        }
                    }
                    foreach (var i in leafUnion)
                    {
                        if (i.Value.Count == s.Count)
                        {
                            var leafClone = new ParsedNode(i.Value.First())
                            {
                                Type = GetCommonBaseClass(i.Value.Select(j => j.Type).ToList()).Name
                            };
                            UniteMarkers(leafClone, i.Value);
                            nextRoot.ParsedNodes.Add(leafClone);
                        }
                    }
                    foreach (var i in treeUnion)
                    {
                        if (i.Value.Count == s.Count)
                        {
                            var subtreeClone = new ParsedFramesTree(i.Value.First())
                            {
                                ParsedNode = { Type = GetCommonBaseClass(i.Value.Select(j => j.ParsedNode.Type).ToList()).Name }
                            };
                            UniteMarkers(subtreeClone.ParsedNode, i.Value.Select(j => j.ParsedNode).ToList());
                            nextRoot.InnerClasses.Add(subtreeClone);
                            queue.Enqueue(i.Value);
                            sync.Enqueue(subtreeClone);
                        }
                    }
                }
                if (root.InnerClasses.Count != 0 || root.ParsedNodes.Count != 0 || root.ParsedNode.Markers.Count != 0)
                {
                    var code = codeHeader.Replace("<%GEN%>", root.GenerateCode(this, false) + "\n<%GEN%>");
                    code = code.Replace("<%GEN%>", "");
                    code = new CodeFormatter(code).FormattedCode;
                    File.WriteAllText($"{commonDirectory}/{kv.Key}.cs", code);
                }
            }
        }
Пример #2
0
        public void Start()
        {
            Console.WriteLine("Generating scenes code for {0} scenes...", scenesForProcessing.Count);
            var generatedScenesPath = $"{directory}/{projectName}.GeneratedScenes";

            if (!Directory.Exists(generatedScenesPath))
            {
                GenerateProjectFiles(generatedScenesPath);
            }
            var scenesPath = $@"{directory}/{projectName}.GeneratedScenes/Scenes";

            RemoveOrphanedGeneratedCodeItems();
            RemoveUpdatingCommonPartsFromCache();
            foreach (var scenePath in allScenes)
            {
                externalSceneToOriginalScenePath.Add(Path.ChangeExtension(scenePath, null), scenePath);
            }
            var sceneToFrameTree = new List <Tuple <string, ParsedFramesTree> >();

            foreach (var scene in scenesForProcessing)
            {
                var bundleName       = sceneToBundleMap[scene.Key];
                var bundleSourcePath = $"{scenesPath}/{bundleName}";
                if (!Directory.Exists(bundleSourcePath))
                {
                    RetryUntilSuccessCreateDirectory(bundleSourcePath);
                }
                currentCookingScene = scene.Key;
                var parsedFramesTree = GenerateParsedFramesTree(scene.Key, scene.Value);
                sceneToFrameTree.Add(new Tuple <string, ParsedFramesTree>(scene.Key, parsedFramesTree));
            }
            foreach (var kv in sceneToFrameTree)
            {
                var parsedFramesTree = kv.Item2;
                currentCookingScene = kv.Item1;
                var k = Path.ChangeExtension(kv.Item1, null);
                k = AssetPath.CorrectSlashes(k);
                var id                = scenesForProcessing[kv.Item1].Id;
                var bundleName        = sceneToBundleMap[kv.Item1];
                var bundleSourcePath  = $"{scenesPath}/{bundleName}";
                var generatedCodePath = bundleSourcePath + "/" + parsedFramesTree.ClassName + ".cs";
                var useful            =
                    parsedFramesTree.ParsedNodes.Count > 0 ||
                    parsedFramesTree.InnerClasses.Count > 0 ||
                    (id != null && (id.StartsWith("@") || id.StartsWith(">")));
                if (!useful)
                {
                    if (File.Exists(generatedCodePath))
                    {
                        File.Delete(generatedCodePath);
                    }
                    continue;
                }
                var code = parsedFramesTree.GenerateCode(this);
                code = code.Replace("<%PROJECT_NAME%>", projectName);
                code = code.Replace("<%NAMESPACE%>", GetBundleNamespace(bundleName));
                code = new CodeFormatter(code).FormattedCode;
                File.WriteAllText(generatedCodePath, code);
            }
            UpdateCache();
            // Collect not loaded scenes which are also contains common parts affected by actually modified and referred to them scenes
            // Because we need those to correctly update common parts. i.e. to calc common parts you need all of common parts referrers
            List <string> reprocessScenes = new List <string>();

            foreach (var kv in codeCookerCache.CommonPartToReferredScenes)
            {
                if (commonParts.ContainsKey(kv.Key))
                {
                    foreach (var scene in kv.Value)
                    {
                        if (!modifiedScenes.Contains(scene))
                        {
                            reprocessScenes.Add(scene);
                        }
                    }
                }
            }
            foreach (var scene in reprocessScenes)
            {
                GenerateParsedFramesTree(scene, Node.CreateFromAssetBundle(scene));
            }
            GenerateCommonParts(scenesPath);
            UpdateCommonPartsCache();
        }