void PrintText(BuildLayout layout)
    {
        MemoryStream stream = new MemoryStream();

        BuildLayoutPrinter.WriteBundleLayout(stream, layout);
        string report = Encoding.ASCII.GetString(stream.ToArray());

        Debug.Log(report);
    }
    public void WhenAssetHasStreamedData_IsReportedCorrectly()
    {
        AddressableAssetGroup group = CreateGroup("Group1");
        string      prefabGUID      = CreateAddressableTexture("t1", group, 256);
        BuildLayout layout          = BuildAndExtractLayout();

        Assert.IsTrue(layout.Groups[0].Bundles[0].Files[0].Assets[0].StreamedSize != 0);
        BuildLayout.SubFile f = layout.Groups[0].Bundles[0].Files[0].SubFiles.First(x => x.Name.EndsWith(".resS"));
        Assert.IsFalse(f.IsSerializedFile);
    }
    public void WhenAssetImplicitlyPulledIntoBundle_ImplicitEntryAndReferencesCreated()
    {
        AddressableAssetGroup group = CreateGroup("Group1");
        string prefabGUID           = CreateAddressablePrefab("p1", group);
        string aGUID = CreateAsset("p2");

        MakePefabReference(prefabGUID, aGUID);

        BuildLayout layout = BuildAndExtractLayout();

        BuildLayout.DataFromOtherAsset oa = layout.Groups[0].Bundles[0].Files[0].OtherAssets.First(x => x.AssetPath.Contains("p2.prefab"));
        Assert.AreEqual(aGUID, oa.AssetGuid);
    }
 public void WhenReferencedObjectIdentifiedWithFilename_ObjectRepresentedInDataFromOtherAssets()
 {
     using (new SpritePackerScope(SpritePackerMode.BuildTimeOnlyAtlas))
     {
         BuildCache.PurgeCache(false);
         AddressableAssetGroup group = CreateGroup("Group1");
         string textureGUID          = CreateSpriteTexture("spritetexture", 256, false);
         MakeAddressable(group, CreateSpriteAtlas("atlas", textureGUID));
         BuildLayout layout = BuildAndExtractLayout();
         BuildLayout.DataFromOtherAsset otherAssets = layout.Groups[0].Bundles[0].Files[0].Assets[0].InternalReferencedOtherAssets[0];
         Assert.IsTrue(otherAssets.AssetPath.StartsWith("library/atlascache", StringComparison.OrdinalIgnoreCase));
         CollectionAssert.Contains(otherAssets.ReferencingAssets, layout.Groups[0].Bundles[0].Files[0].Assets[0]);
     }
 }
 internal BuildLayout BuildAndExtractLayout()
 {
     try
     {
         BuildLayout layout = null;
         BuildLayoutGenerationTask.s_LayoutCompleteCallback = (x) => layout = x;
         m_Settings.BuildPlayerContentImpl();
         return(layout);
     }
     finally
     {
         BuildLayoutGenerationTask.s_LayoutCompleteCallback = null;
     }
 }
        /// <summary>
        /// Runs the build task with the injected context.
        /// </summary>
        /// <returns>The success or failure ReturnCode</returns>
        public ReturnCode Run()
        {
            BuildLayout layout = CreateBuildLayout();

            Directory.CreateDirectory(Path.GetDirectoryName(kLayoutTextFile));
            using (FileStream s = File.Open(kLayoutTextFile, FileMode.Create))
                BuildLayoutPrinter.WriteBundleLayout(s, layout);

            UnityEngine.Debug.Log($"Build layout written to {kLayoutTextFile}");

            s_LayoutCompleteCallback?.Invoke(layout);

            return(ReturnCode.Success);
        }
    public void WhenBundleReferencesAnotherBundle_ExternalReferenceExists()
    {
        AddressableAssetGroup group = CreateGroup("Group1");
        string prefabGUID           = CreateAddressablePrefab("p1", group);

        AddressableAssetGroup group2 = CreateGroup("Group2");
        string g2p1GUID = CreateAddressablePrefab("g2p1", group2);

        MakePefabReference(prefabGUID, g2p1GUID);

        BuildLayout layout = BuildAndExtractLayout();

        CollectionAssert.Contains(layout.Groups[0].Bundles[0].Dependencies, layout.Groups[1].Bundles[0]);
        Assert.AreEqual(layout.Groups[0].Bundles[0].Files[0].Assets[0].ExternallyReferencedAssets[0], layout.Groups[1].Bundles[0].Files[0].Assets[0]);
    }
    public void WhenAllContentsOfAnAssetAreStripped_ExplicitAssetHasNoObjects()
    {
        AddressableAssetGroup group = CreateGroup("Group1");
        string   assetPath          = $"{TempPath}/testpreset.preset";
        Material obj      = new Material(Shader.Find("Transparent/Diffuse"));
        Preset   myPreset = new Preset(obj);

        AssetDatabase.CreateAsset(myPreset, assetPath);
        GameObject.DestroyImmediate(obj);
        AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceSynchronousImport | ImportAssetOptions.ForceUpdate);
        string guid = AssetDatabase.AssetPathToGUID(assetPath);

        MakeAddressable(group, guid);
        BuildLayout layout = BuildAndExtractLayout();

        Assert.AreEqual(0, layout.Groups[0].Bundles[0].Files[0].Assets[0].SerializedSize);
    }
        public static Dictionary <string, object> PlacePrograms2D(List <DeptData> deptData, List <double> kpuProgramWidthList, double minAllowedDim = 5, int designSeed = 5, bool checkAspectRatio = false)
        {
            if (deptData == null)
            {
                return(null);
            }
            List <DeptData> deptDataInp = deptData;

            deptData = deptDataInp.Select(x => new DeptData(x)).ToList(); // example of deep copy
            List <List <Polygon2d> > polyPorgsAdded = new List <List <Polygon2d> >();
            List <ProgramData>       progDataNew    = new List <ProgramData>();

            for (int i = 0; i < deptData.Count; i++)
            {
                DeptData deptItem = deptData[i];
                //if (i == 0)
                if ((deptItem.DepartmentType.IndexOf(BuildLayout.KPU.ToLower()) != -1 ||
                     deptItem.DepartmentType.IndexOf(BuildLayout.KPU.ToUpper()) != -1))
                {
                    Dictionary <string, object> placedPrimaryProg = BuildLayout.PlaceKPUPrograms(deptData[i].PolyAssignedToDept, deptData[i].ProgramsInDept, kpuProgramWidthList);
                    deptData[i].ProgramsInDept = (List <ProgramData>)placedPrimaryProg["ProgramData"];
                }
                else
                {
                    Dictionary <string, object> placedSecondaryProg = BuildLayout.PlaceREGPrograms(deptData[i], minAllowedDim, designSeed, checkAspectRatio);
                    if (placedSecondaryProg != null)
                    {
                        deptData[i].ProgramsInDept = (List <ProgramData>)placedSecondaryProg["ProgramData"];
                    }
                    else
                    {
                        deptData[i].ProgramsInDept = null;
                    }
                }
            }
            List <DeptData> newDeptData = deptData.Select(x => new DeptData(x)).ToList(); // example of deep copy

            return(new Dictionary <string, object>
            {
                { "DeptData", (newDeptData) }
            });
        }
    public void WhenBundleContainsMultipleFiles_FilesAndSizesMatchArchiveContent()
    {
        AddressableAssetGroup groupScenes  = CreateGroup("SceneGroup");
        AddressableAssetGroup textureGroup = CreateGroup("TextureGroup");
        string scenePath = $"{TempPath}/scene.unity";
        Scene  scene1    = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene);

        new GameObject().AddComponent <TestBehaviourWithReference>();
        EditorSceneManager.SaveScene(scene1, scenePath);
        AddressableAssetEntry e = m_Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(scenePath), groupScenes);

        EditorSceneManager.NewScene(NewSceneSetup.EmptyScene);
        CreateAddressableTexture("t1", textureGroup, 256);

        BuildLayout layout = BuildAndExtractLayout();

        BundledAssetGroupSchema schema = m_Settings.groups.First(x => x.HasSchema <BundledAssetGroupSchema>()).GetSchema <BundledAssetGroupSchema>();
        string path = schema.BuildPath.GetValue(m_Settings);

        foreach (BuildLayout.Bundle bundle in layout.Groups.SelectMany(x => x.Bundles))
        {
            AssertEditorBundleDetailsMatchPhysicalBundle(Path.Combine(path, bundle.Name), bundle);
        }
    }
        private BuildLayout CreateBuildLayout()
        {
            LayoutLookupTables lookup = new LayoutLookupTables();

            foreach (string bundleName in m_WriteData.FileToBundle.Values.Distinct())
            {
                BuildLayout.Bundle bundle = new BuildLayout.Bundle();
                bundle.Name = bundleName;
                string path = m_Parameters.GetOutputFilePathForIdentifier(bundle.Name);
                UnityEngine.BuildCompression compression = m_Parameters.GetCompressionForIdentifier(bundle.Name);
                bundle.FileSize    = (ulong)new FileInfo(path).Length;
                bundle.Compression = compression.compression.ToString();
                lookup.Bundles.Add(bundle.Name, bundle);
            }

            // create files
            foreach (KeyValuePair <string, string> fileBundle in m_WriteData.FileToBundle)
            {
                BuildLayout.Bundle bundle = lookup.Bundles[fileBundle.Value];
                BuildLayout.File   f      = new BuildLayout.File();
                f.Name = fileBundle.Key;

                WriteResult result = m_Results.WriteResults[f.Name];
                foreach (ResourceFile rf in result.resourceFiles)
                {
                    var sf = new BuildLayout.SubFile();
                    sf.IsSerializedFile = rf.serializedFile;
                    sf.Name             = rf.fileAlias;
                    sf.Size             = (ulong)new FileInfo(rf.fileName).Length;
                    f.SubFiles.Add(sf);
                }

                bundle.Files.Add(f);
                lookup.Files.Add(f.Name, f);
            }

            // create assets
            foreach (KeyValuePair <GUID, List <string> > assetFile in m_WriteData.AssetToFiles)
            {
                BuildLayout.File          file = lookup.Files[assetFile.Value[0]];
                BuildLayout.ExplicitAsset a    = new BuildLayout.ExplicitAsset();
                a.Guid      = assetFile.Key.ToString();
                a.AssetPath = AssetDatabase.GUIDToAssetPath(a.Guid);
                file.Assets.Add(a);
                lookup.GuidToExplicitAsset.Add(a.Guid, a);
            }

            Dictionary <string, List <BuildLayout.DataFromOtherAsset> > guidToPulledInBuckets = new Dictionary <string, List <BuildLayout.DataFromOtherAsset> >();

            foreach (BuildLayout.File file in lookup.Files.Values)
            {
                Dictionary <string, AssetBucket> buckets = new Dictionary <string, AssetBucket>();
                WriteResult writeResult = m_Results.WriteResults[file.Name];
                List <ObjectSerializedInfo> sceneObjects = new List <ObjectSerializedInfo>();

                foreach (ObjectSerializedInfo info in writeResult.serializedObjects)
                {
                    string sourceGuid = string.Empty;
                    if (info.serializedObject.guid.Empty())
                    {
                        if (info.serializedObject.filePath.Equals("temp:/assetbundle", StringComparison.OrdinalIgnoreCase))
                        {
                            file.BundleObjectInfo      = new BuildLayout.AssetBundleObjectInfo();
                            file.BundleObjectInfo.Size = info.header.size;
                            continue;
                        }
                        else if (info.serializedObject.filePath.StartsWith("temp:/preloaddata", StringComparison.OrdinalIgnoreCase))
                        {
                            file.PreloadInfoSize = (int)info.header.size;
                            continue;
                        }
                        else if (info.serializedObject.filePath.StartsWith("temp:/", StringComparison.OrdinalIgnoreCase))
                        {
                            sceneObjects.Add(info);
                            continue;
                        }
                        else if (!string.IsNullOrEmpty(info.serializedObject.filePath))
                        {
                            AssetBucket pathBucket = GetOrCreate(buckets, info.serializedObject.filePath.ToString());
                            pathBucket.isFilePathBucket = true;
                            pathBucket.objs.Add(info);
                            continue;
                        }
                    }

                    AssetBucket bucket = GetOrCreate(buckets, info.serializedObject.guid.ToString());
                    bucket.objs.Add(info);
                }

                if (sceneObjects.Count > 0)
                {
                    BuildLayout.ExplicitAsset sceneAsset = file.Assets.First(x => x.AssetPath.EndsWith(".unity"));
                    AssetBucket bucket = GetOrCreate(buckets, sceneAsset.Guid);
                    bucket.objs.AddRange(sceneObjects);
                }

                // Update buckets with a reference to their explicit asset
                file.Assets.ForEach(eAsset =>
                {
                    if (!buckets.TryGetValue(eAsset.Guid, out AssetBucket b))
                    {
                        b = GetOrCreate(buckets, eAsset.Guid); // some assets might not pull in any objects
                    }
                    b.ExplictAsset = eAsset;
                });

                // Create entries for buckets that are implicitly pulled in
                Dictionary <string, BuildLayout.DataFromOtherAsset> guidToOtherData = new Dictionary <string, BuildLayout.DataFromOtherAsset>();
                foreach (AssetBucket bucket in buckets.Values.Where(x => x.ExplictAsset == null))
                {
                    string assetPath = bucket.isFilePathBucket ? bucket.guid : AssetDatabase.GUIDToAssetPath(bucket.guid);
                    if (assetPath.EndsWith(".cs", StringComparison.OrdinalIgnoreCase) || assetPath.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
                    {
                        file.MonoScriptCount++;
                        file.MonoScriptSize += bucket.CalcObjectSize();
                        continue;
                    }
                    var otherData = new BuildLayout.DataFromOtherAsset();
                    otherData.AssetPath      = assetPath;
                    otherData.AssetGuid      = bucket.guid;
                    otherData.SerializedSize = bucket.CalcObjectSize();
                    otherData.StreamedSize   = bucket.CalcStreamedSize();
                    otherData.ObjectCount    = bucket.objs.Count;
                    file.OtherAssets.Add(otherData);
                    guidToOtherData[otherData.AssetGuid] = otherData;

                    if (!guidToPulledInBuckets.TryGetValue(otherData.AssetGuid, out List <BuildLayout.DataFromOtherAsset> bucketList))
                    {
                        bucketList = guidToPulledInBuckets[otherData.AssetGuid] = new List <BuildLayout.DataFromOtherAsset>();
                    }
                    bucketList.Add(otherData);
                }

                // Add references
                foreach (BuildLayout.ExplicitAsset asset in file.Assets)
                {
                    AssetBucket bucket = buckets[asset.Guid];
                    asset.SerializedSize = bucket.CalcObjectSize();
                    asset.StreamedSize   = bucket.CalcStreamedSize();

                    IEnumerable <ObjectIdentifier> refs = null;
                    if (m_DependencyData.AssetInfo.TryGetValue(new GUID(asset.Guid), out AssetLoadInfo info))
                    {
                        refs = info.referencedObjects;
                    }
                    else
                    {
                        refs = m_DependencyData.SceneInfo[new GUID(asset.Guid)].referencedObjects;
                    }
                    foreach (string refGUID in refs.Select(x => x.guid.Empty() ? x.filePath : x.guid.ToString()).Distinct())
                    {
                        if (guidToOtherData.TryGetValue(refGUID, out BuildLayout.DataFromOtherAsset dfoa))
                        {
                            dfoa.ReferencingAssets.Add(asset);
                            asset.InternalReferencedOtherAssets.Add(dfoa);
                        }
                        else if (buckets.TryGetValue(refGUID, out AssetBucket refBucket))
                        {
                            asset.InternalReferencedExplicitAssets.Add(refBucket.ExplictAsset);
                        }
                        else if (lookup.GuidToExplicitAsset.TryGetValue(refGUID, out BuildLayout.ExplicitAsset refAsset))
                        {
                            asset.ExternallyReferencedAssets.Add(refAsset);
                        }
                    }
                }
            }

            BuildLayout layout = new BuildLayout();

            // This is the addressables section. Everything above could technically be moved to SBP.
            {
                AddressableAssetsBuildContext aaContext = (AddressableAssetsBuildContext)m_AaBuildContext;
                // Map from GUID to AddrssableAssetEntry
                Dictionary <string, AddressableAssetEntry> guidToEntry = aaContext.assetEntries.ToDictionary(x => x.guid, x => x);

                // create groups
                foreach (AddressableAssetGroup group in aaContext.Settings.groups)
                {
                    var grp = new BuildLayout.Group();
                    grp.Name = group.Name;
                    grp.Guid = group.Guid;

                    foreach (AddressableAssetGroupSchema schema in group.Schemas)
                    {
                        var sd = new BuildLayout.SchemaData();
                        sd.Guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(schema));
                        sd.Type = schema.GetType().Name.ToString();

                        BundledAssetGroupSchema bSchema = schema as BundledAssetGroupSchema;
                        if (bSchema != null)
                        {
                            sd.KvpDetails.Add(new Tuple <string, string>("PackingMode", bSchema.BundleMode.ToString()));
                            sd.KvpDetails.Add(new Tuple <string, string>("Compression", bSchema.Compression.ToString()));
                        }
                        grp.Schemas.Add(sd);
                    }

                    lookup.GroupLookup.Add(group.Guid, grp);
                    layout.Groups.Add(grp);
                }

                // go through all the bundles and put them in groups
                foreach (BuildLayout.Bundle b in lookup.Bundles.Values)
                {
                    if (aaContext.bundleToImmediateBundleDependencies.TryGetValue(b.Name, out List <string> deps))
                    {
                        b.Dependencies = deps.Select(x => lookup.Bundles[x]).Where(x => b != x).ToList();
                    }
                    if (aaContext.bundleToExpandedBundleDependencies.TryGetValue(b.Name, out List <string> deps2))
                    {
                        b.ExpandedDependencies = deps2.Select(x => lookup.Bundles[x]).Where(x => b != x).ToList();
                    }

                    if (aaContext.bundleToAssetGroup.TryGetValue(b.Name, out string grpName))
                    {
                        lookup.GroupLookup[grpName].Bundles.Add(b);
                    }
                    else
                    {
                        layout.BuiltInBundles.Add(b);
                    }
                }

                // Apply the addressable name to the asset
                foreach (BuildLayout.ExplicitAsset a in BuildLayoutHelpers.EnumerateAssets(layout))
                {
                    if (guidToEntry.TryGetValue(a.Guid, out AddressableAssetEntry entry))
                    {
                        a.AddressableName = entry.address;
                    }
                }

                // The addressables build script can rename the bundles
                foreach (BuildLayout.Bundle b in BuildLayoutHelpers.EnumerateBundles(layout))
                {
                    if (m_BundleNameRemap.TryGetValue(b.Name, out string newName))
                    {
                        b.Name = newName;
                    }
                }
            }

            return(layout);
        }
        [MultiReturn(new[] { "DeptData", "LeftOverPolys" })]//"CirculationPolys", "OtherDeptMainPoly"
        public static Dictionary <string, object> PlaceDepartments2D(List <DeptData> deptData, List <Polygon2d> buildingOutline, List <double> kpuDepthList, List <double> kpuWidthList,
                                                                     double acceptableWidth, double polyDivision = 8, int designSeed = 50, bool noExternalWall = false,
                                                                     bool unlimitedKPU = true, bool mode3D = false, double totalBuildingHeight = 60, double avgFloorHeight = 15)
        {
            if (polyDivision >= 1 && polyDivision < 30)
            {
                BuildLayout.SPACING = polyDivision; BuildLayout.SPACING2 = polyDivision;
            }
            double          circulationFreq = 8;
            List <DeptData> deptDataInp     = deptData;

            deptData = deptDataInp.Select(x => new DeptData(x)).ToList(); // example of deep copy

            Dictionary <string, object> deptArrangement = new Dictionary <string, object>();
            double count = 0, eps = 5;
            Random rand = new Random();
            bool   deptPlaced = false;
            Random ran = new Random(designSeed);
            bool   stackOptionsDept = deptData[0].StackingOptions;
            bool   stackOptionsProg = deptData[0].ProgramsInDept[0].StackingOptions;

            while (deptPlaced == false && count < BuildLayout.MAXCOUNT)//MAXCOUNT
            {
                double parameter = BasicUtility.RandomBetweenNumbers(ran, 0.9, 0.5);
                if (!stackOptionsDept)
                {
                    parameter = 0;
                }
                //parameter = 0;
                Trace.WriteLine("PLACE DEPT STARTS , Lets arrange dept again ++++++++++++++++ : " + count);
                deptArrangement = BuildLayout.DeptPlacer(deptData, buildingOutline, kpuDepthList, kpuWidthList, acceptableWidth, circulationFreq, designSeed, noExternalWall, unlimitedKPU, stackOptionsDept, stackOptionsProg, parameter);
                if (deptArrangement != null)
                {
                    List <DeptData>          deptDataUpdated = (List <DeptData>)deptArrangement["DeptData"];
                    List <List <Polygon2d> > deptAllPolys    = new List <List <Polygon2d> >();
                    for (int i = 0; i < deptDataUpdated.Count; i++)
                    {
                        deptAllPolys.Add(deptDataUpdated[i].PolyAssignedToDept);
                    }
                    List <Polygon2d> deptPolysTogether = new List <Polygon2d>();
                    for (int i = 0; i < deptAllPolys.Count; i++)
                    {
                        if (ValidateObject.CheckPolyList(deptAllPolys[i]))
                        {
                            deptPolysTogether.AddRange(deptAllPolys[i]);
                        }
                    }

                    if (deptAllPolys.Count > 0)
                    {
                        Trace.WriteLine("dept arrangement not null, lets check further");
                    }
                    for (int i = 0; i < deptAllPolys.Count; i++)
                    {
                        List <Polygon2d> eachDeptPoly = deptAllPolys[i];
                        if (ValidateObject.CheckPolyList(eachDeptPoly))
                        {
                            deptPlaced = true;
                        }
                        else
                        {
                            deptPlaced = false; Trace.WriteLine("dept arrangement bad polys, rejected"); break;
                        }
                        bool orthoResult = ValidateObject.CheckPolygon2dListOrtho(deptPolysTogether, eps);
                        Trace.WriteLine("The poly formed is : " + orthoResult);
                        if (orthoResult)
                        {
                            deptPlaced = true;
                        }
                        else
                        {
                            deptPlaced = false; Trace.WriteLine("dept arrangement non orthogonal, rejected"); break;
                        }
                    }
                }
                else
                {
                    deptPlaced  = false;
                    designSeed += 1;
                    Trace.WriteLine("DeptPlacer returned null, rejected for: " + count);
                }
                count += 1;
                Trace.WriteLine(" EXIT PLACE DEPARTMENTS +++++++++++++++++++++++++++++++++");
            }// end of while loop
            return(deptArrangement);
        }