public void TestCollectionItemIdentifierWithDuplicates() { var container = new AssetPropertyGraphContainer(new AssetNodeContainer { NodeBuilder = { NodeFactory = new AssetNodeFactory() } }); var asset = new Types.MyAsset2 { MyStrings = { "aaa", "bbb", "ccc" } }; var ids = CollectionItemIdHelper.GetCollectionItemIds(asset.MyStrings); ids.Add(0, IdentifierGenerator.Get(100)); ids.Add(1, IdentifierGenerator.Get(200)); ids.Add(2, IdentifierGenerator.Get(100)); var assetItem = new AssetItem("MyAsset", asset); Assert.Equal(IdentifierGenerator.Get(100), ids[0]); Assert.Equal(IdentifierGenerator.Get(200), ids[1]); Assert.Equal(IdentifierGenerator.Get(100), ids[2]); var graph = AssetQuantumRegistry.ConstructPropertyGraph(container, assetItem, null); Assert.IsAssignableFrom <AssetObjectNode>(graph.RootNode); Assert.True(CollectionItemIdHelper.TryGetCollectionItemIds(asset.MyStrings, out ids)); Assert.Equal(3, ids.KeyCount); Assert.Equal(0, ids.DeletedCount); Assert.Equal(IdentifierGenerator.Get(100), ids[0]); Assert.Equal(IdentifierGenerator.Get(200), ids[1]); Assert.NotEqual(IdentifierGenerator.Get(100), ids[2]); Assert.NotEqual(IdentifierGenerator.Get(200), ids[2]); }
internal static void Initialize() { if (!PlatformFolders.IsVirtualFileSystemInitialized) { PlatformFolders.ApplicationDataSubDirectory = typeof(Module).Assembly.GetName().Name; } AssemblyRegistry.Register(typeof(Module).Assembly, AssemblyCommonCategories.Assets); AssetQuantumRegistry.RegisterAssembly(typeof(Module).Assembly); RuntimeHelpers.RunModuleConstructor(typeof(Asset).Module.ModuleHandle); }
protected CopyPasteTest([NotNull] Asset asset) { Container = new AssetPropertyGraphContainer(new AssetNodeContainer { NodeBuilder = { NodeFactory = new AssetNodeFactory() } }); AssetItem = new AssetItem("MyAsset", asset); var assetGraph = AssetQuantumRegistry.ConstructPropertyGraph(Container, AssetItem, null); Assert.IsAssignableFrom <EntityHierarchyPropertyGraph>(assetGraph); AssetGraph = (EntityHierarchyPropertyGraph)assetGraph; }
public void TestSimpleCollectionUpdate() { var container = new AssetPropertyGraphContainer(new PackageSession(), new AssetNodeContainer()); var asset = new Types.MyAsset2 { MyStrings = { "aaa", "bbb", "ccc" } }; var assetItem = new AssetItem("MyAsset", asset); var graph = AssetQuantumRegistry.ConstructPropertyGraph(container, assetItem, null); var node = ((IGraphNode)graph.RootNode).TryGetChild(nameof(Types.MyAsset2.MyStrings)); //var ids = CollectionItemIdHelper.TryGetCollectionItemIds(asset.MyStrings, out itemIds); }
public void TestSimpleConstruction() { var container = new AssetPropertyGraphContainer(new PackageSession(), new AssetNodeContainer()); var asset = new Types.MyAsset1 { MyString = "String" }; var assetItem = new AssetItem("MyAsset", asset); var graph = AssetQuantumRegistry.ConstructPropertyGraph(container, assetItem, null); Assert.IsAssignableFrom <AssetNode>(graph.RootNode); }
/// <inheritdoc /> public override bool ProcessDeserializedData(AssetPropertyGraphContainer graphContainer, object targetRootObject, Type targetMemberType, ref object data, bool isRootDataObjectReference, AssetId?sourceId, YamlAssetMetadata <OverrideType> overrides, YamlAssetPath basePath) { var asset = (AssetCompositeHierarchy <TAssetPartDesign, TAssetPart>)targetRootObject; var hierarchy = data as AssetCompositeHierarchyData <TAssetPartDesign, TAssetPart>; if (hierarchy == null) { return(false); } // Create a temporary asset to host the hierarchy to paste, so we have a property graph to manipulate it. var tempAsset = (AssetCompositeHierarchy <TAssetPartDesign, TAssetPart>)Activator.CreateInstance(asset.GetType()); tempAsset.Hierarchy = hierarchy; // Use temporary containers so that any created nodes are discarded after the processing. var tempNodeContainer = new AssetNodeContainer { NodeBuilder = { NodeFactory = new AssetNodeFactory() } }; var definition = AssetQuantumRegistry.GetDefinition(asset.GetType()); var rootNode = tempNodeContainer.GetOrCreateNode(tempAsset); // If different asset or if at least one part already exists, create a custom clone. if (asset.Id != sourceId || hierarchy.Parts.Values.Any(part => asset.ContainsPart(part.Part.Id))) { // Clone again to create new ids for any IIdentifiable, but keep references to external object intact. var cloneExternalReferences = ExternalReferenceCollector.GetExternalReferences(definition, rootNode); hierarchy = AssetCloner.Clone(hierarchy, AssetClonerFlags.GenerateNewIdsForIdentifiableObjects, cloneExternalReferences, out var idRemapping); // Remap indices of parts in Hierarchy.Part AssetCloningHelper.RemapIdentifiablePaths(overrides, idRemapping, basePath); // Make new base instances ids in case the part are inherited. AssetPartsAnalysis.GenerateNewBaseInstanceIds(hierarchy); // Update the temporary asset with this cloned hierarchy. rootNode[nameof(AssetCompositeHierarchy <TAssetPartDesign, TAssetPart> .Hierarchy)].Update(hierarchy); } // Collect all referenceable objects from the target asset (where we're pasting) var targetPropertyGraph = graphContainer.TryGetGraph(asset.Id); var referenceableObjects = IdentifiableObjectCollector.Collect(targetPropertyGraph.Definition, targetPropertyGraph.RootNode); // Replace references in the hierarchy being pasted by the real objects from the target asset. var externalReferences = new HashSet <Guid>(ExternalReferenceCollector.GetExternalReferences(definition, rootNode).Select(x => x.Id)); var visitor = new ObjectReferencePathGenerator(definition) { ShouldOutputReference = x => externalReferences.Contains(x) }; visitor.Visit(rootNode); FixupObjectReferences.FixupReferences(tempAsset, visitor.Result, referenceableObjects, true); data = hierarchy; return(true); }
protected void BuildGraph() { var baseGraph = AssetQuantumRegistry.ConstructPropertyGraph(Container, BaseAssetItem, null); Assert.IsAssignableFrom <MyAssetBasePropertyGraph>(baseGraph); BaseGraph = (MyAssetBasePropertyGraph)baseGraph; var derivedGraph = AssetQuantumRegistry.ConstructPropertyGraph(Container, DerivedAssetItem, null); Assert.IsAssignableFrom <MyAssetBasePropertyGraph>(baseGraph); DerivedGraph = (MyAssetBasePropertyGraph)derivedGraph; DerivedGraph.RefreshBase(BaseGraph); }
private void RegisterComponent(EntityComponent component) { if (component != null && ComponentType.IsInstanceOfType(component)) { var rootNode = controller.GameSideNodeContainer.GetOrCreateNode(component); var listener = new AssetGraphNodeChangeListener(rootNode, AssetQuantumRegistry.GetDefinition(typeof(EntityHierarchyAssetBase))); listener.Initialize(); listener.ValueChanged += ComponentPropertyChanged; listener.ItemChanged += ComponentPropertyChanged; registeredListeners.Add(component, listener); } }
public void TestSimpleConstruction() { var container = new AssetPropertyGraphContainer(new AssetNodeContainer { NodeBuilder = { NodeFactory = new AssetNodeFactory() } }); var asset = new Types.MyAsset1 { MyString = "String" }; var assetItem = new AssetItem("MyAsset", asset); var graph = AssetQuantumRegistry.ConstructPropertyGraph(container, assetItem, null); Assert.IsAssignableFrom <AssetObjectNode>(graph.RootNode); }
public void TestSimpleCollectionUpdate() { var container = new AssetPropertyGraphContainer(new AssetNodeContainer { NodeBuilder = { NodeFactory = new AssetNodeFactory() } }); var asset = new Types.MyAsset2 { MyStrings = { "aaa", "bbb", "ccc" } }; var assetItem = new AssetItem("MyAsset", asset); var graph = AssetQuantumRegistry.ConstructPropertyGraph(container, assetItem, null); var node = graph.RootNode[nameof(Types.MyAsset2.MyStrings)]; //var ids = CollectionItemIdHelper.TryGetCollectionItemIds(asset.MyStrings, out itemIds); }
public static Types.MyAssetHierarchyPropertyGraph BuildAssetAndGraph(int rootCount, int depth, int childPerPart, Action <AssetCompositeHierarchyData <Types.MyPartDesign, Types.MyPart> > initializeProperties = null) { var container = new AssetPropertyGraphContainer(new AssetNodeContainer { NodeBuilder = { NodeFactory = new AssetNodeFactory() } }); var asset = BuildHierarchy(rootCount, depth, childPerPart); var assetItem = new AssetItem("MyAsset", asset); initializeProperties?.Invoke(asset.Hierarchy); var graph = (Types.MyAssetHierarchyPropertyGraph)AssetQuantumRegistry.ConstructPropertyGraph(container, assetItem, null); return(graph); }
public static void Initialize() { RuntimeHelpers.RunModuleConstructor(typeof(SpriteFontAsset).Module.ModuleHandle); RuntimeHelpers.RunModuleConstructor(typeof(MaterialKeys).Module.ModuleHandle); RuntimeHelpers.RunModuleConstructor(typeof(Model).Module.ModuleHandle); RuntimeHelpers.RunModuleConstructor(typeof(PrefabAsset).Module.ModuleHandle); AssemblyRegistry.Register(typeof(Module).Assembly, AssemblyCommonCategories.Assets); // We need access to the AssetQuantumRegistry from the SessionTemplateGenerator so for now we register graph types in the module initializer. AssetQuantumRegistry.RegisterAssembly(typeof(Module).Assembly); // Register default template XenkoTemplates.Register(); // Initialize translation TranslationManager.Instance.RegisterProvider(new GettextTranslationProvider()); }
private AssetPropertyGraph CreateScene(params Entity[] entities) { var scene = new SceneAsset(); foreach (var entity in entities) { scene.Hierarchy.RootParts.Add(entity); scene.Hierarchy.Parts.Add(new EntityDesign(entity)); } var assetItem = new AssetItem("", scene); var propertyGraph = AssetQuantumRegistry.ConstructPropertyGraph(propertyGraphContainer, assetItem, null); propertyGraphContainer.RegisterGraph(propertyGraph); return(propertyGraph); }
/// <inheritdoc/> protected override Dictionary <Guid, IIdentifiable> CollectIdentifiableObjects() { var allEntities = Game.ContentScene.Yield().BreadthFirst(x => x.Children).SelectMany(x => x.Entities).BreadthFirst(x => x.Transform.Children.Select(y => y.Entity)); var definition = AssetQuantumRegistry.GetDefinition(Asset.Asset.GetType()); var identifiableObjects = new Dictionary <Guid, IIdentifiable>(); foreach (var entityNode in allEntities.Select(x => GameSideNodeContainer.GetOrCreateNode(x))) { foreach (var identifiable in IdentifiableObjectCollector.Collect(definition, entityNode)) { identifiableObjects.Add(identifiable.Key, identifiable.Value); } } return(identifiableObjects); }
/// <inheritdoc/> protected override Dictionary <Guid, IIdentifiable> CollectIdentifiableObjects() { var allElements = RootElements.Values.BreadthFirst(x => x.VisualChildren); var definition = AssetQuantumRegistry.GetDefinition(Asset.Asset.GetType()); var identifiableObjects = new Dictionary <Guid, IIdentifiable>(); foreach (var entityNode in allElements.Select(x => GameSideNodeContainer.GetOrCreateNode(x))) { foreach (var identifiable in IdentifiableObjectCollector.Collect(definition, entityNode)) { identifiableObjects.Add(identifiable.Key, identifiable.Value); } } return(identifiableObjects); }
public void TestCollectionConstruction() { var container = new AssetPropertyGraphContainer(new PackageSession(), new AssetNodeContainer()); var asset = new Types.MyAsset2 { MyStrings = { "aaa", "bbb", "ccc" } }; var assetItem = new AssetItem("MyAsset", asset); var graph = AssetQuantumRegistry.ConstructPropertyGraph(container, assetItem, null); Assert.IsAssignableFrom <AssetNode>(graph.RootNode); CollectionItemIdentifiers ids; Assert.True(CollectionItemIdHelper.TryGetCollectionItemIds(asset.MyStrings, out ids)); Assert.AreEqual(3, ids.KeyCount); Assert.AreEqual(0, ids.DeletedCount); Assert.True(ids.ContainsKey(0)); Assert.True(ids.ContainsKey(1)); Assert.True(ids.ContainsKey(2)); }
protected IEnumerable <TAssetPart> ClonePartsForGameSide([NotNull] AssetCompositeHierarchy <TAssetPartDesign, TAssetPart> asset, [NotNull] IEnumerable <TAssetPart> parts) { var flags = SubHierarchyCloneFlags.RemoveOverrides; var sourceContainer = Asset.PropertyGraph.Container.NodeContainer; var targetContainer = GameSideNodeContainer; var clone = AssetCompositeHierarchyPropertyGraph <TAssetPartDesign, TAssetPart> .CloneSubHierarchies(sourceContainer, targetContainer, asset, parts.Select(p => p.Id), flags, out _); // Collect external references after cloning, we need to fix them up! var rootNode = GameSideNodeContainer.GetOrCreateNode(clone); var definition = AssetQuantumRegistry.GetDefinition(asset.GetType()); var unresolvedReferences = ExternalReferenceCollector.GetExternalReferenceAccessors(definition, rootNode); // Retrieve all available game-side identifiable objects, so we can try to resolve external references with items from this collection. var identifiableObjects = CollectIdentifiableObjects(); foreach (var reference in unresolvedReferences) { if (identifiableObjects.TryGetValue(reference.Key.Id, out var realObject)) { // Target object found, let's update the reference with the real game-side object. foreach (var accessor in reference.Value) { accessor.UpdateValue(realObject); } } else { // Target object not found, let's clear the reference since the currently set object could be asset-side, or a temporary proxy, etc. foreach (var accessor in reference.Value) { accessor.UpdateValue(null); } } } return(clone.RootParts); }
internal static void Initialize() { AssemblyRegistry.Register(typeof(Module).Assembly, AssemblyCommonCategories.Assets); AssetQuantumRegistry.RegisterAssembly(typeof(Module).Assembly); RuntimeHelpers.RunModuleConstructor(typeof(Asset).Module.ModuleHandle); }