public override bool Upgrade(PackageSession session, ILogger log, Package dependentPackage, PackageDependency dependency, Package dependencyPackage, IList<PackageLoadingAssetFile> assetFiles) { // Paradox 1.1 projects didn't have their dependency properly updated (they might have been marked as 1.0). // We know they are 1.1 only because there is a .props file. // This check shouldn't be necessary from 1.2. var packagePath = dependentPackage.FullPath; var propsFilePath = UPath.Combine(packagePath.GetParent(), (UFile)(packagePath.GetFileName() + ".props")); if (!File.Exists(propsFilePath) && dependency.Version.MinVersion < new PackageVersion("1.1.0-beta")) { log.Error("Can't upgrade old projects from {0} 1.0 to 1.1", dependency.Name); return false; } // Nothing to do for now, most of the work is already done by individual asset upgraders // We can later add logic here for package-wide upgrades (i.e. GameSettingsAsset) if (dependency.Version.MinVersion < new PackageVersion("1.2.0-beta")) { // UIImageGroups and SpriteGroups asset have been merged into a single SpriteSheet => rename the assets and modify the tag var uiImageGroups = assetFiles.Where(f => f.FilePath.GetFileExtension() == ".pdxuiimage"); var spitesGroups = assetFiles.Where(f => f.FilePath.GetFileExtension() == ".pdxsprite"); RenameAndChangeTag(assetFiles, uiImageGroups, "!UIImageGroup"); RenameAndChangeTag(assetFiles, spitesGroups, "!SpriteGroup"); } return true; }
public EffectCompileCommand(AssetCompilerContext context, UDirectory baseUrl, string effectName, CompilerParameters compilerParameters, Package package) { this.context = context; this.baseUrl = baseUrl; this.effectName = effectName; this.compilerParameters = compilerParameters; this.package = package; }
/// <summary> /// Initializes a new instance of <see cref="AssetMigrationContext"/>. /// </summary> /// <param name="package"></param> /// <param name="assetReference"></param> /// <param name="assetFullPath"></param> /// <param name="log"></param> public AssetMigrationContext(Package package, IReference assetReference, string assetFullPath, ILogger log) { if (log == null) throw new ArgumentNullException(nameof(log)); Package = package; AssetReference = assetReference; AssetFullPath = assetFullPath; Log = new AssetLogger(package, assetReference, assetFullPath, log); }
/// <summary> /// Initializes a new instance of the <see cref="PackageLoadingAssetFile" /> class. /// </summary> /// <param name="package">The package this asset will be part of.</param> /// <param name="filePath">The relative file path (from default asset folder).</param> /// <param name="sourceFolder">The source folder (optional, can be null).</param> /// <exception cref="System.ArgumentException">filePath must be relative</exception> public PackageLoadingAssetFile(Package package, UFile filePath, UDirectory sourceFolder) { if (filePath.IsAbsolute) throw new ArgumentException("filePath must be relative", filePath); SourceFolder = UPath.Combine(package.RootDirectory, sourceFolder ?? package.GetDefaultAssetFolder()); FilePath = UPath.Combine(SourceFolder, filePath); }
public AssetLogger(Package package, IReference assetReference, string assetFullPath, ILogger loggerToForward) { this.package = package; this.assetReference = assetReference; this.assetFullPath = assetFullPath; this.loggerToForward = loggerToForward; ActivateLog(LogMessageType.Debug); }
/// <summary> /// Initializes a new instance of the <see cref="PackageStore"/> class. /// </summary> /// <exception cref="System.InvalidOperationException">Unable to find a valid Xenko installation path</exception> private PackageStore(string installationPath = null, string defaultPackageName = "Xenko", string defaultPackageVersion = XenkoVersion.CurrentAsText) { // TODO: these are currently hardcoded to Xenko DefaultPackageName = defaultPackageName; DefaultPackageVersion = new PackageVersion(defaultPackageVersion); defaultPackageDirectory = DirectoryHelper.GetPackageDirectory(defaultPackageName); // 1. Try to use the specified installation path if (installationPath != null) { if (!DirectoryHelper.IsInstallationDirectory(installationPath)) { throw new ArgumentException("Invalid Xenko installation path [{0}]".ToFormat(installationPath), "installationPath"); } globalInstallationPath = installationPath; } // 2. Try to resolve an installation path from the path of this assembly // We need to be able to use the package manager from an official Xenko install as well as from a developer folder if (globalInstallationPath == null) { globalInstallationPath = DirectoryHelper.GetInstallationDirectory(DefaultPackageName); } // If there is no root, this is an error if (globalInstallationPath == null) { throw new InvalidOperationException("Unable to find a valid Xenko installation or dev path"); } // Preload default package var logger = new LoggerResult(); var defaultPackageFile = DirectoryHelper.GetPackageFile(defaultPackageDirectory, DefaultPackageName); defaultPackage = Package.Load(logger, defaultPackageFile, GetDefaultPackageLoadParameters()); if (defaultPackage == null) { throw new InvalidOperationException("Error while loading default package from [{0}]: {1}".ToFormat(defaultPackageFile, logger.ToText())); } defaultPackage.IsSystem = true; // A flag variable just to know if it is a bare bone development directory isDev = defaultPackageDirectory != null && DirectoryHelper.IsRootDevDirectory(defaultPackageDirectory); // Check if we are in a root directory with store/packages facilities if (NugetStore.IsStoreDirectory(globalInstallationPath)) { packagesDirectory = UPath.Combine(globalInstallationPath, (UDirectory)NugetStore.DefaultGamePackagesDirectory); store = new NugetStore(globalInstallationPath); } else { // We should exit from here if NuGet is not configured. MessageBox.Show($"Unexpected installation. Cannot find a proper NuGet configuration for [{defaultPackageName}] in [{globalInstallationPath}]", "Installation Error", MessageBoxButtons.OK, MessageBoxIcon.Error); Environment.Exit(1); } }
/// <summary> /// Create a <see cref="Package"/> that can be used to compile an <see cref="AssetItem"/> by analyzing and resolving its dependencies. /// </summary> /// <returns>The package packageSession that can be used to compile the asset item.</returns> public static Package CreateCompilePackageFromAsset(this PackageSession session, AssetItem originalAssetItem) { // create the compile root package and package session var assetPackageCloned = new Package(); var compilePackageSession = new PackageSession(assetPackageCloned); AddAssetToCompilePackage(session, originalAssetItem, assetPackageCloned); return assetPackageCloned; }
private static void FillPackageDependencies(Package rootPackage, bool isRecursive, ICollection<Package> packagesFound, bool storeOnly = false) { var session = rootPackage.Session; if (session == null && (rootPackage.Meta.Dependencies.Count > 0 || rootPackage.LocalDependencies.Count > 0)) { throw new InvalidOperationException("Cannot query package with dependencies when it is not attached to a session"); } // 1. Load store package foreach (var packageDependency in rootPackage.Meta.Dependencies) { var package = session.Packages.Find(packageDependency); if (package == null) { continue; } if (!packagesFound.Contains(package)) { packagesFound.Add(package); if (isRecursive) { FillPackageDependencies(package, isRecursive, packagesFound, storeOnly); } } } if (storeOnly) { return; } // 2. Load local packages foreach (var packageReference in rootPackage.LocalDependencies) { var package = session.Packages.Find(packageReference.Id); if (package == null) { continue; } if (!packagesFound.Contains(package)) { packagesFound.Add(package); if (isRecursive) { FillPackageDependencies(package, isRecursive, packagesFound, storeOnly); } } } }
/// <summary> /// Initializes a new instance of the <see cref="PackageSession"/> class. /// </summary> public PackageSession(Package package) { packages = new PackageCollection(); packagesCopy = new PackageCollection(); assemblyContainer = new AssemblyContainer(); packages.CollectionChanged += PackagesCollectionChanged; if (package != null) { Packages.Add(package); } }
public static GraphicsPlatform GetGraphicsPlatform(this AssetCompilerContext context, Package package) { // If we have a command line override, use it first string graphicsApi; if (context.OptionProperties.TryGetValue("SiliconStudioXenkoGraphicsApi", out graphicsApi)) return (GraphicsPlatform)Enum.Parse(typeof(GraphicsPlatform), graphicsApi); // Ohterwise, use game settings, or default as fallback var settings = package.GetGameSettingsAsset(); return settings == null ? context.Platform.GetDefaultGraphicsPlatform() : RenderingSettings.GetGraphicsPlatform(context.Platform, settings.Get<RenderingSettings>(context.Profile).PreferredGraphicsPlatform); }
/// <summary> /// Initializes a new instance of the <see cref="PackageSession"/> class. /// </summary> public PackageSession(Package package) { constraintProvider.AddConstraint(PackageStore.Instance.DefaultPackageName, new VersionSpec(PackageStore.Instance.DefaultPackageVersion.ToSemanticVersion())); packages = new PackageCollection(); packagesCopy = new PackageCollection(); assemblyContainer = new AssemblyContainer(); packages.CollectionChanged += PackagesCollectionChanged; if (package != null) { Packages.Add(package); } }
/// <inheritdoc/> public override bool UpgradeAfterAssetsLoaded(PackageSession session, ILogger log, Package dependentPackage, PackageDependency dependency, Package dependencyPackage, PackageVersionRange dependencyVersionBeforeUpdate) { if (dependencyVersionBeforeUpdate.MinVersion < new PackageVersion("1.3.0-alpha02")) { // Add everything as root assets (since we don't know what the project was doing in the code before) foreach (var assetItem in dependentPackage.Assets) { if (!AssetRegistry.IsAssetTypeAlwaysMarkAsRoot(assetItem.Asset.GetType())) dependentPackage.RootAssets.Add(new AssetReference<Asset>(assetItem.Id, assetItem.Location)); } } return true; }
/// <summary> /// This method is called when a package needs to be tracked /// </summary> /// <param name="package">The package to track.</param> private void TrackPackage(Package package) { if (packages.Contains(package)) return; packages.Add(package); foreach (var asset in package.Assets) { TrackAsset(asset); } package.Assets.CollectionChanged += Assets_CollectionChanged; }
public static void AddLoadingFromSession(this ShaderGeneratorContextBase context, Package package) { var previousGetAssetFriendlyName = context.GetAssetFriendlyName; var previousFindAsset = context.FindAsset; // Setup the GetAssetFriendlyName callback context.GetAssetFriendlyName = runtimeAsset => { string assetFriendlyName = null; if (previousGetAssetFriendlyName != null) { assetFriendlyName = previousGetAssetFriendlyName(runtimeAsset); } if (string.IsNullOrEmpty(assetFriendlyName)) { var referenceAsset = AttachedReferenceManager.GetAttachedReference(runtimeAsset); assetFriendlyName = string.Format("{0}:{1}", referenceAsset.Id, referenceAsset.Url); } return assetFriendlyName; }; // Setup the FindAsset callback context.FindAsset = runtimeAsset => { object newAsset = null; if (previousFindAsset != null) { newAsset = previousFindAsset(runtimeAsset); } if (newAsset != null) { return newAsset; } var reference = AttachedReferenceManager.GetAttachedReference(runtimeAsset); var assetItem = package.Session.FindAsset(reference.Id) ?? package.Session.FindAsset(reference.Url); if (assetItem == null) { return null; } return assetItem.Asset; }; }
/// <summary> /// This method is called when a package needs to be un-tracked /// </summary> /// <param name="package">The package to un-track.</param> private void UnTrackPackage(Package package) { if (!packages.Contains(package)) return; package.Assets.CollectionChanged -= Assets_CollectionChanged; foreach (var asset in package.Assets) { UnTrackAsset(asset); } packages.Remove(package); }
/// <summary> /// Creates a new Paradox package with the specified name /// </summary> /// <param name="name">Name of the package</param> /// <returns>A new package instance</returns> public static Package NewPackage(string name) { var package = new Package { Meta = { Name = name, Version = new PackageVersion("1.0.0.0") }, }; // Add dependency to latest Paradox package package.Meta.Dependencies.Add(ParadoxConfig.GetLatestPackageDependency()); // Setup the assets folder by default package.Profiles.Add(PackageProfile.NewShared()); return package; }
public static void AddLoadingFromSession(this ShaderGeneratorContextBase shaderGeneratorContext, Package package) { shaderGeneratorContext.FindAsset = material => { if (material.Descriptor != null) { return material.Descriptor; } var reference = AttachedReferenceManager.GetAttachedReference(material); var assetItem = package.Session.FindAsset(reference.Id) ?? package.Session.FindAsset(reference.Url); if (assetItem == null) { return null; } return (IMaterialDescriptor)assetItem.Asset; }; }
/// <summary> /// Create a <see cref="PackageSession"/> that can be used to compile an <see cref="AssetItem"/> by analyzing and resolving its dependencies. /// </summary> /// <returns>The package packageSession that can be used to compile the asset item.</returns> public static PackageSession CreateCompilePackageFromAsset(this PackageSession session, AssetItem originalAssetItem) { if (originalAssetItem == null) throw new ArgumentNullException("originalAssetItem"); // Find the asset from the session var assetItem = originalAssetItem.Package.FindAsset(originalAssetItem.Id); if (assetItem == null) { throw new ArgumentException("Cannot find the specified AssetItem instance in the session"); } // Calculate dependencies var dependencies = session.DependencyManager.ComputeDependencies(assetItem, AssetDependencySearchOptions.Out | AssetDependencySearchOptions.Recursive); var assetItemRootCloned = dependencies.Item.Clone(); // Store the fullpath to the sourcefolder, this avoid us to clone hierarchy of packages assetItemRootCloned.SourceFolder = assetItem.FullPath.GetParent(); // create the compile root package and package session var assetPackageCloned = new Package(); var compilePackageSession = new PackageSession(assetPackageCloned); assetPackageCloned.Assets.Add(assetItemRootCloned); // For each asset item dependency, clone it in the new package foreach (var assetLink in dependencies.LinksOut) { // Only add assets not already added (in case of circular dependencies) if (assetPackageCloned.Assets.Find(assetLink.Item.Id) == null) { // create a copy of the asset item and add it to the appropriate compile package var itemCloned = assetLink.Item.Clone(); // Store the fullpath to the sourcefolder, this avoid us to clone hierarchy of packages itemCloned.SourceFolder = assetLink.Item.FullPath.GetParent(); assetPackageCloned.Assets.Add(itemCloned); } } return compilePackageSession; }
public static void AddAssetToCompilePackage(this PackageSession session, AssetItem originalAssetItem, Package assetPackageCloned) { if (originalAssetItem == null) throw new ArgumentNullException("originalAssetItem"); // Find the asset from the session var assetItem = originalAssetItem.Package.FindAsset(originalAssetItem.Id); if (assetItem == null) { throw new ArgumentException("Cannot find the specified AssetItem instance in the session"); } // Calculate dependencies // Search only for references var dependencies = session.DependencyManager.ComputeDependencies(assetItem.Id, AssetDependencySearchOptions.Out | AssetDependencySearchOptions.Recursive, ContentLinkType.Reference); if (dependencies == null) throw new InvalidOperationException("The asset doesn't exist in the dependency manager anymore"); var assetItemRootCloned = dependencies.Item.Clone(); // Store the fullpath to the sourcefolder, this avoid us to clone hierarchy of packages assetItemRootCloned.SourceFolder = assetItem.FullPath.GetParent(); if (assetPackageCloned.Assets.Find(assetItemRootCloned.Id) == null) assetPackageCloned.Assets.Add(assetItemRootCloned); // For each asset item dependency, clone it in the new package foreach (var assetLink in dependencies.LinksOut) { // Only add assets not already added (in case of circular dependencies) if (assetPackageCloned.Assets.Find(assetLink.Item.Id) == null) { // create a copy of the asset item and add it to the appropriate compile package var itemCloned = assetLink.Item.Clone(); // Store the fullpath to the sourcefolder, this avoid us to clone hierarchy of packages itemCloned.SourceFolder = assetLink.Item.FullPath.GetParent(); assetPackageCloned.Assets.Add(itemCloned); } } }
public static void Build(Package package, string outputDirectory = null) { if (package == null) throw new ArgumentNullException("package"); var meta = new NuGet.ManifestMetadata(); package.Meta.ToNugetManifest(meta); var builder = new NuGet.PackageBuilder(); builder.Populate(meta); // TODO this is not working var files = new List<NuGet.ManifestFile>() { NewFile(@"Bin\**\*.exe", "Bin"), NewFile(@"Bin\**\*.vsix", "Bin"), NewFile(@"Bin\**\*.so", "Bin"), NewFile(@"Bin\**\*.a", "Bin"), NewFile(@"Bin\**\*.md", "Bin"), NewFile(@"Bin\**\*.html", "Bin"), NewFile(@"Bin\**\*.config", "Bin"), NewFile(@"Bin\**\*.dll", "Bin"), NewFile(@"Bin\**\*.xml", "Bin"), NewFile(@"Bin\**\*.winmd", "Bin"), NewFile(@"Targets\*.targets", "Targets"), }; // Handle Assets var rootDir = package.RootDirectory; var newPackage = new Package { Meta = package.Meta }; foreach (var profile in package.Profiles) { var target = "Assets/" + profile.Name; foreach (var assetFolder in profile.AssetFolders) { // TODO: handle exclude in asset folders //files.Add(NewFile(source, target, @"**\*.cs;**\*.hlsl;**\*.csproj;**\*.csproj.user;**\obj\**")); files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.pdxsl", target)); files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.pdxfx", target)); } var targetProfile = new PackageProfile(profile.Name); targetProfile.AssetFolders.Add(new AssetFolder(target)); newPackage.Profiles.Add(targetProfile); } // Handle templates var targetFolder = new TemplateFolder("Templates"); foreach (var templateFolder in package.TemplateFolders) { var source = templateFolder.Path.MakeRelative(rootDir) + "/**"; UDirectory target = targetFolder.Path; if (templateFolder.Group != null) { target = UPath.Combine(target, templateFolder.Group); } var excludeFiles = templateFolder.Exclude; files.Add(NewFile(source, target, excludeFiles)); // Add template files foreach (var templateFile in templateFolder.Files) { var newTemplateFile = templateFile.MakeRelative(templateFolder.Path); if (templateFolder.Group != null) { newTemplateFile = UPath.Combine(templateFolder.Group, newTemplateFile); } newTemplateFile = UPath.Combine(targetFolder.Path, newTemplateFile); targetFolder.Files.Add(newTemplateFile); } } // Create temp package for archive newPackage.TemplateFolders.Add(targetFolder); var newPackageFileName = "temp" + Guid.NewGuid() + ".pdxpkg"; newPackage.FullPath = package.RootDirectory + "/" + newPackageFileName; var result = newPackage.Save(); if (result.HasErrors) { throw new InvalidOperationException(result.ToText()); // TODO throw error } files.Add(NewFile(newPackageFileName, package.Meta.Name + Package.PackageFileExtension)); // Add files builder.PopulateFiles(package.RootDirectory, files); outputDirectory = outputDirectory ?? Environment.CurrentDirectory; // Save the nupkg var outputPath = GetOutputPath(builder, outputDirectory); bool isExistingPackage = File.Exists(outputPath); if (isExistingPackage) { File.Delete(outputPath); } try { using (Stream stream = File.Create(outputPath)) { builder.Save(stream); } } catch { if (!isExistingPackage && File.Exists(outputPath)) { File.Delete(outputPath); } throw; } File.Delete(newPackage.FullPath); }
public override bool UpgradeBeforeAssembliesLoaded(PackageSession session, ILogger log, Package dependentPackage, PackageDependency dependency, Package dependencyPackage) { if (dependency.Version.MinVersion < new PackageVersion("1.4.0-alpha01")) { // Only load workspace for C# assemblies (default includes VB but not added as a NuGet package) var csharpWorkspaceAssemblies = new[] { Assembly.Load("Microsoft.CodeAnalysis.Workspaces"), Assembly.Load("Microsoft.CodeAnalysis.CSharp.Workspaces"), Assembly.Load("Microsoft.CodeAnalysis.Workspaces.Desktop") }; var workspace = MSBuildWorkspace.Create(ImmutableDictionary<string, string>.Empty, MefHostServices.Create(csharpWorkspaceAssemblies)); var tasks = dependentPackage.Profiles .SelectMany(profile => profile.ProjectReferences) .Select(projectReference => UPath.Combine(dependentPackage.RootDirectory, projectReference.Location)) .Distinct() .Select(projectFullPath => Task.Run(() => UpgradeProject(workspace, projectFullPath))) .ToArray(); Task.WaitAll(tasks); } return true; }
public override bool Upgrade(PackageSession session, ILogger log, Package dependentPackage, PackageDependency dependency, Package dependencyPackage, IList<PackageLoadingAssetFile> assetFiles) { // Paradox 1.1 projects didn't have their dependency properly updated (they might have been marked as 1.0). // We know they are 1.1 only because there is a .props file. // This check shouldn't be necessary from 1.2. var packagePath = dependentPackage.FullPath; var propsFilePath = UPath.Combine(packagePath.GetParent(), (UFile)(packagePath.GetFileName() + ".props")); if (!File.Exists(propsFilePath) && dependency.Version.MinVersion < new PackageVersion("1.1.0-beta")) { log.Error("Can't upgrade old projects from {0} 1.0 to 1.1", dependency.Name); return false; } // Nothing to do for now, most of the work is already done by individual asset upgraders // We can later add logic here for package-wide upgrades (i.e. GameSettingsAsset) if (dependency.Version.MinVersion < new PackageVersion("1.2.0-beta")) { // UIImageGroups and SpriteGroups asset have been merged into a single SpriteSheet => rename the assets and modify the tag var uiImageGroups = assetFiles.Where(f => f.FilePath.GetFileExtension() == ".pdxuiimage"); var spritesGroups = assetFiles.Where(f => f.FilePath.GetFileExtension() == ".pdxsprite"); RenameAndChangeTag(assetFiles, uiImageGroups, "!UIImageGroup"); RenameAndChangeTag(assetFiles, spritesGroups, "!SpriteGroup"); } if (dependency.Version.MinVersion < new PackageVersion("1.3.0-alpha01")) { // Create GameSettingsAsset GameSettingsAsset.UpgraderVersion130.Upgrade(session, log, dependentPackage, dependency, dependencyPackage, assetFiles); } if (dependency.Version.MinVersion < new PackageVersion("1.3.0-alpha02")) { // Delete EffectLogAsset foreach (var assetFile in assetFiles) { if (assetFile.FilePath.GetFileName() == EffectLogAsset.DefaultFile) { assetFile.Deleted = true; } } } if (dependency.Version.MinVersion < new PackageVersion("1.4.0-beta")) { // Update file extensions with Xenko prefix var legacyAssets = from assetFile in assetFiles where !assetFile.Deleted let extension = assetFile.FilePath.GetFileExtension() where extension.StartsWith(".pdx") select new { AssetFile = assetFile, NewExtension = ".xk" + extension.Substring(4) }; foreach (var legacyAsset in legacyAssets.ToArray()) { // Load asset data, so the renamed file will have it's AssetContent set if (legacyAsset.AssetFile.AssetContent == null) legacyAsset.AssetFile.AssetContent = File.ReadAllBytes(legacyAsset.AssetFile.FilePath); // Change legacy namespaces and default effect names in all shader source files // TODO: Use syntax analysis? What about shaders referenced in other assets? if (legacyAsset.NewExtension == ".xksl" || legacyAsset.NewExtension == ".xkfx" || legacyAsset.NewExtension == ".xkeffectlog") { var sourceText = System.Text.Encoding.UTF8.GetString(legacyAsset.AssetFile.AssetContent); var newSourceText = sourceText.Replace("Paradox", "Xenko"); if (newSourceText != sourceText) { legacyAsset.AssetFile.AssetContent = System.Text.Encoding.UTF8.GetBytes(newSourceText); } } // Create asset copy with new extension ChangeFileExtension(assetFiles, legacyAsset.AssetFile, legacyAsset.NewExtension); } // Force loading of user settings with old extension var userSettings = dependentPackage.UserSettings; // Change package extension dependentPackage.FullPath = new UFile(dependentPackage.FullPath.GetFullPathWithoutExtension(), Package.PackageFileExtension); // Make sure all assets are upgraded RunAssetUpgradersUntilVersion(log, dependentPackage, XenkoConfig.PackageName, assetFiles, PackageVersion.Parse("1.4.0-beta")); } if (dependency.Version.MinVersion < new PackageVersion("1.5.0-alpha01")) { RunAssetUpgradersUntilVersion(log, dependentPackage, XenkoConfig.PackageName, assetFiles, PackageVersion.Parse("1.5.0-alpha01")); } if (dependency.Version.MinVersion < new PackageVersion("1.5.0-alpha02")) { // Ideally, this should be part of asset upgrader but we can't upgrade multiple assets at once yet var modelAssets = assetFiles.Where(f => f.FilePath.GetFileExtension() == ".xkm3d").Select(x => x.AsYamlAsset()).ToArray(); var animAssets = assetFiles.Where(f => f.FilePath.GetFileExtension() == ".xkanim").Select(x => x.AsYamlAsset()).ToArray(); var sceneAssets = assetFiles.Where(f => f.FilePath.GetFileExtension() == ".xkscene").Select(x => x.AsYamlAsset()).ToArray(); // Select models with at least two nodes var modelAssetsWithSekeleton = modelAssets .Where(model => ((IEnumerable)model.DynamicRootNode.Nodes).Cast<object>().Count() > 1).ToArray(); var animToModelMapping = new Dictionary<PackageLoadingAssetFile.YamlAsset, PackageLoadingAssetFile.YamlAsset>(); // Find associations in scene foreach (var sceneAsset in sceneAssets) { var hierarchy = sceneAsset.DynamicRootNode.Hierarchy; foreach (dynamic entity in hierarchy.Entities) { var components = entity.Entity.Components; var animationComponent = components["AnimationComponent.Key"]; var model = components["ModelComponent.Key"]?.Model; if (animationComponent != null && model != null) { var modelReference = DynamicYamlExtensions.ConvertTo<AssetReference<Asset>>(model); var modelAsset = modelAssetsWithSekeleton.FirstOrDefault(x => x.Asset.AssetPath == modelReference.Location); foreach (var animation in animationComponent.Animations) { var animationReference = DynamicYamlExtensions.ConvertTo<AssetReference<Asset>>(animation.Value); var animationAsset = animAssets.FirstOrDefault(x => x.Asset.AssetPath == animationReference.Location); if (modelAsset != null && animationAsset != null) { animToModelMapping[animationAsset] = modelAsset; } } } } } // Find associations when sharing same source file foreach (var animationAsset in animAssets) { // Comparing absolute path of assets var modelAsset = modelAssetsWithSekeleton.FirstOrDefault( x => UPath.Combine(animationAsset.Asset.AssetPath.GetParent(), new UFile((string)animationAsset.DynamicRootNode.Source)) == UPath.Combine(x.Asset.AssetPath.GetParent(), new UFile((string)x.DynamicRootNode.Source))); if (modelAsset != null) { animToModelMapping[animationAsset] = modelAsset; } } var modelToSkeletonMapping = new Dictionary<PackageLoadingAssetFile.YamlAsset, PackageLoadingAssetFile.YamlAsset>(); // For each model asset, create skeleton assets foreach (var modelAsset in modelAssetsWithSekeleton) { var skeletonAsset = new PackageLoadingAssetFile(modelAsset.Asset.FilePath.GetFullPathWithoutExtension() + " Skeleton.xkskel", modelAsset.Asset.SourceFolder) { AssetContent = System.Text.Encoding.UTF8.GetBytes("!Skeleton\r\nId: " + Guid.NewGuid()) }; using (var skeletonAssetYaml = skeletonAsset.AsYamlAsset()) { // Set source skeletonAssetYaml.DynamicRootNode.Source = modelAsset.DynamicRootNode.Source; skeletonAssetYaml.DynamicRootNode.SourceHash = modelAsset.DynamicRootNode.SourceHash; // To be on the safe side, mark everything as preserved var nodes = modelAsset.DynamicRootNode.Nodes; foreach (var node in nodes) { node.Preserve = true; } skeletonAssetYaml.DynamicRootNode.Nodes = nodes; skeletonAssetYaml.DynamicRootNode.ScaleImport = modelAsset.DynamicRootNode.ScaleImport; // Update model to point to this skeleton modelAsset.DynamicRootNode.Skeleton = new AssetReference<Asset>(Guid.Parse((string)skeletonAssetYaml.DynamicRootNode.Id), skeletonAsset.AssetPath.MakeRelative(modelAsset.Asset.AssetPath.GetParent())); modelToSkeletonMapping.Add(modelAsset, skeletonAssetYaml); } assetFiles.Add(skeletonAsset); } // Update animation to point to skeleton, and set preview default model foreach (var animToModelEntry in animToModelMapping) { var animationAsset = animToModelEntry.Key; var modelAsset = animToModelEntry.Value; var skeletonAsset = modelToSkeletonMapping[modelAsset]; animationAsset.DynamicRootNode.Skeleton = new AssetReference<Asset>(Guid.Parse((string)skeletonAsset.DynamicRootNode.Id), skeletonAsset.Asset.AssetPath.MakeRelative(animationAsset.Asset.AssetPath.GetParent())); animationAsset.DynamicRootNode.PreviewModel = new AssetReference<Asset>(Guid.Parse((string)modelAsset.DynamicRootNode.Id), modelAsset.Asset.AssetPath.MakeRelative(animationAsset.Asset.AssetPath.GetParent())); } // Remove Nodes from models foreach (var modelAsset in modelAssets) { modelAsset.DynamicRootNode.Nodes = DynamicYamlEmpty.Default; modelAsset.DynamicRootNode["~Base"].Asset.Nodes = DynamicYamlEmpty.Default; } // Save back foreach (var modelAsset in modelAssets) modelAsset.Dispose(); foreach (var animAsset in animAssets) animAsset.Dispose(); } return true; }
private void RunAssetUpgradersUntilVersion(ILogger log, Package dependentPackage, string dependencyName, IList<PackageLoadingAssetFile> assetFiles, PackageVersion maxVersion) { foreach (var assetFile in assetFiles) { if (assetFile.Deleted) continue; var context = new AssetMigrationContext(dependentPackage, log); AssetMigration.MigrateAssetIfNeeded(context, assetFile, dependencyName, maxVersion); } }
/// <summary> /// Performs the package migration, before assets are loaded /// </summary> /// <param name="session">The session.</param> /// <param name="log">The log.</param> /// <param name="dependentPackage">The source package.</param> /// <param name="dependency">The dependency.</param> /// <param name="dependencyPackage">The dependency package.</param> /// <param name="assetFiles">The asset files.</param> /// <returns></returns> public abstract bool Upgrade(PackageSession session, ILogger log, Package dependentPackage, PackageDependency dependency, Package dependencyPackage, IList<PackageLoadingAssetFile> assetFiles);
public static GraphicsProfile GetGraphicsProfile(Package package) { var packageSharedProfile = package.Profiles.FindSharedProfile(); if (packageSharedProfile == null) return 0; return packageSharedProfile.Properties.Get(DefaultGraphicsProfile); }
/// <summary> /// Saves a .props file for the specified package, containing the paradox version (only Major.Minor) /// used to compile the package. /// </summary> /// <param name="package">The package.</param> public static void SaveProperties(Package package) { // Props file is in the same folder as the pdxpkg file, just with a ".props" extension. var packagePath = package.FullPath; var propsFilePath = UPath.Combine(packagePath.GetParent(), (UFile)(packagePath.GetFileName() + ".props")) ; var projectCollection = new Microsoft.Build.Evaluation.ProjectCollection(); var project = new Microsoft.Build.Evaluation.Project(projectCollection); var commonPropertyGroup = project.Xml.AddPropertyGroup(); var dependencies = package.FindDependencies(false, false, true); // Add Paradox version var pdxVersion = dependencies.FirstOrDefault(d => d.Meta.Name == "Paradox"); if (pdxVersion != null) { var versionText = pdxVersion.Meta.Version.Version.Major + "." + pdxVersion.Meta.Version.Version.Minor; commonPropertyGroup.AddProperty("SiliconStudioPackageParadoxVersion", versionText); } if (File.Exists(propsFilePath)) { File.Delete(propsFilePath); } project.Save(propsFilePath); }
/// <summary> /// Performs a preprocessing step of package migration, before assembly references are loaded. /// </summary> /// <param name="session">The session.</param> /// <param name="log">The log.</param> /// <param name="dependentPackage">The source package.</param> /// <param name="dependency">The dependency.</param> /// <param name="dependencyPackage">The dependency package.</param> /// <returns></returns> public virtual bool UpgradeBeforeAssembliesLoaded(PackageSession session, ILogger log, Package dependentPackage, PackageDependency dependency, Package dependencyPackage) { return true; }
public static void MarkPackageDirty(Package package) { package.IsDirty = true; }
/// <summary> /// Performs the second step of package migration, after assets have been loaded. /// </summary> /// <param name="session">The session.</param> /// <param name="log">The log.</param> /// <param name="dependentPackage">The source package.</param> /// <param name="dependency">The dependency.</param> /// <param name="dependencyPackage">The dependency package.</param> /// <param name="dependencyVersionBeforeUpdate">The version before the update.</param> /// <returns></returns> public virtual bool UpgradeAfterAssetsLoaded(PackageSession session, ILogger log, Package dependentPackage, PackageDependency dependency, Package dependencyPackage, PackageVersionRange dependencyVersionBeforeUpdate) { return true; }
// Build a full GameSettings from a package public static GameSettings CreateFromPackage(Package package, PlatformType platform) { var result = new GameSettings(); // Default settings var sharedProfile = package.Profiles.FindSharedProfile(); if (sharedProfile != null) { var sceneAsset = sharedProfile.Properties.Get(DefaultScene); if (sceneAsset != null) result.DefaultSceneUrl = sceneAsset.Location; result.DefaultBackBufferWidth = sharedProfile.Properties.Get(BackBufferWidth); result.DefaultBackBufferHeight = sharedProfile.Properties.Get(BackBufferHeight); result.DefaultGraphicsProfileUsed = sharedProfile.Properties.Get(DefaultGraphicsProfile); } // Platform-specific settings have priority if (platform != PlatformType.Shared) { var platformProfile = package.Profiles.FirstOrDefault(o => o.Platform == platform); if (platformProfile != null) { var customProfile = platformProfile.Properties.Get(DefaultGraphicsProfile); if (customProfile > 0) result.DefaultGraphicsProfileUsed = customProfile; } } return result; }