/// <summary> /// Performs custom actions after an attribute in the DOM node subtree changed</summary> /// <param name="sender">Sender (root DOM node)</param> /// <param name="e">Attribute change event args</param> protected override void OnAttributeChanged(object sender, AttributeEventArgs e) { if (Validating && !m_undoingOrRedoing) { if (e.DomNode.Parent.Is <Group>() && e.AttributeInfo == ElementLabelAttribute) { var subGraph = e.DomNode.Parent.Cast <Group>(); if (e.DomNode.Is <Element>()) { // the name of a sub-node has changed, needs to update group pin names that are not manually set SyncGroupPinNamesFromModuleName(subGraph, e.DomNode); } } else if (e.DomNode.Is <GroupPin>() && e.AttributeInfo == PinNameAttributeAttribute) { if (e.DomNode.Parent != null) { var subGraph = e.DomNode.Parent.Cast <Group>(); // ensure group pin names are unique at local level UniqueNamer uniqueName = new UniqueNamer(); GroupPin childGrpPin = e.DomNode.Cast <GroupPin>(); foreach (var grpPin in subGraph.InputGroupPins) { if (grpPin != childGrpPin) { uniqueName.Name((string)grpPin.Name); } } foreach (var grpPin in subGraph.OutputGroupPins) { if (grpPin != childGrpPin) { uniqueName.Name((string)grpPin.Name); } } string unique = uniqueName.Name((string)childGrpPin.Name); if (unique != childGrpPin.Name) { childGrpPin.Name.SetString(unique); } // Reset IsDefaultName. Ignore the suffix because there are typically multiple // circuit elements in a group and the child group pin doesn't know about // our unique namer. var defaultName = childGrpPin.DefaultName(childGrpPin.IsInputSide); string ourRoot; int ourSuffix; uniqueName.Parse(unique, out ourRoot, out ourSuffix); childGrpPin.IsDefaultName = defaultName == ourRoot; UpdateParentGroupPinName(childGrpPin.IsInputSide, childGrpPin); } } } base.OnAttributeChanged(sender, e); }
public void TestSuffixes() { UniqueNamer testSpace = new UniqueNamer(' '); Assert.AreEqual(testSpace.Name("a"), "a"); Assert.AreEqual(testSpace.Name("a"), "a 1"); UniqueNamer testDash = new UniqueNamer('-'); Assert.AreEqual(testDash.Name("a"), "a"); Assert.AreEqual(testDash.Name("a"), "a-1"); UniqueNamer testForwardSlash = new UniqueNamer('/'); Assert.AreEqual(testForwardSlash.Name("a"), "a"); Assert.AreEqual(testForwardSlash.Name("a"), "a/1"); UniqueNamer testBackSlash = new UniqueNamer('\\'); Assert.AreEqual(testBackSlash.Name("a"), "a"); Assert.AreEqual(testBackSlash.Name("a"), "a\\1"); UniqueNamer testParens = new UniqueNamer('('); Assert.AreEqual(testParens.Name("a"), "a"); Assert.AreEqual(testParens.Name("a"), "a(1)"); Assert.Throws <ArgumentException>(delegate { UniqueNamer bad = new UniqueNamer('@'); }); }
public void TestName() { UniqueNamer test = new UniqueNamer(); Assert.AreEqual(test.Name("a"), "a"); Assert.AreEqual(test.Name("a1"), "a1"); Assert.AreEqual(test.Name("a"), "a_1"); Assert.AreEqual(test.Name("a_1"), "a_2"); }
/// <summary> /// Performs custom actions after an attribute in the DOM node subtree changed</summary> /// <param name="sender">Sender (root DOM node)</param> /// <param name="e">Attribute change event args</param> protected override void OnAttributeChanged(object sender, AttributeEventArgs e) { if (Validating && !m_undoingOrRedoing) { if (e.DomNode.Parent.Is <Group>() && e.AttributeInfo == ElementLabelAttribute) { var subGraph = e.DomNode.Parent.Cast <Group>(); if (e.DomNode.Is <Element>()) { // the name of a sub-node has changed, needs to update group pin names that are not manually set SyncGroupPinNamesFromModuleName(subGraph, e.DomNode); } } else if (e.DomNode.Is <GroupPin>() && e.AttributeInfo == PinNameAttributeAttribute) { if (e.DomNode.Parent != null) { var subGraph = e.DomNode.Parent.Cast <Group>(); // ensure group pin names are unique at local level UniqueNamer uniqueName = new UniqueNamer(); GroupPin childGrpPin = e.DomNode.Cast <GroupPin>(); foreach (var pin in subGraph.Inputs) { var grpPin = pin.Cast <GroupPin>(); if (grpPin != childGrpPin) { uniqueName.Name(grpPin.Name); } } foreach (var pin in subGraph.Outputs) { var grpPin = pin.Cast <GroupPin>(); if (grpPin != childGrpPin) { uniqueName.Name(grpPin.Name); } } string unique = uniqueName.Name(childGrpPin.Name); if (unique != childGrpPin.Name) { childGrpPin.Name = unique; } // try to reset IsDefaultName childGrpPin.IsDefaultName = childGrpPin.Name == childGrpPin.DefaultName(childGrpPin.IsInputSide); UpdateParentGroupPinName(childGrpPin.IsInputSide, childGrpPin); } } } base.OnAttributeChanged(sender, e); }
public void TestMinNumDigits() { UniqueNamer test = new UniqueNamer('_', 5); test.Name("a"); Assert.AreEqual(test.Name("a"), "a_00001"); Assert.Throws <NotSupportedException>(delegate { UniqueNamer bad = new UniqueNamer('_', 11); }); }
public void TestChange() { UniqueNamer test = new UniqueNamer(); test.Name("a"); test.Change("a", "b"); Assert.AreEqual(test.Name("a"), "a"); Assert.AreEqual(test.Name("b"), "b_1"); }
public void TestRetire() { UniqueNamer test = new UniqueNamer(); test.Name("a"); string a_1 = test.Name("a"); // should be a_1 test.Retire("a"); Assert.AreEqual(test.Name("a"), "a"); Assert.AreEqual(test.Name("a"), "a_2"); }
private DomNode CreatePrefab(IEnumerable <IGameObject> gobs) { UniqueNamer uniqueNamer = new UniqueNamer(); DomNode[] temp = new DomNode[1]; List <IGameObject> copyList = new List <IGameObject>(); AABB bound = new AABB(); foreach (IGameObject gameObject in SelectedGobs) { IBoundable boundable = gameObject.As <IBoundable>(); bound.Extend(boundable.BoundingBox); Matrix4F world = TransformUtils.ComputeWorldTransform(gameObject); temp[0] = gameObject.As <DomNode>(); DomNode[] copies = DomNode.Copy(temp); copies[0].InitializeExtensions(); IGameObject copy = copies[0].As <IGameObject>(); copy.Name = uniqueNamer.Name(copy.Name); TransformUtils.SetTransform(copy, world); copyList.Add(copy); } DomNode prefab = new DomNode(Schema.prefabType.Type, Schema.prefabRootElement); var list = prefab.GetChildList(Schema.prefabType.gameObjectChild); Vec3F center = bound.Center; foreach (IGameObject gob in copyList) { gob.Translation = gob.Translation - center; gob.UpdateTransform(); list.Add(gob.As <DomNode>()); } return(prefab); }
private DomNode CreatePrefab(IEnumerable <object> gobs) { UniqueNamer uniqueNamer = new UniqueNamer(); DomNode[] temp = new DomNode[1]; var copyList = new List <object>(); AABB bound = new AABB(); foreach (var gameObject in SelectedGobs) { IBoundable boundable = gameObject.As <IBoundable>(); bound.Extend(boundable.BoundingBox); var trans = gameObject.As <ITransformable>(); var world = (trans != null) ? TransformUtils.ComputeWorldTransform(trans) : Matrix4F.Identity; temp[0] = gameObject.As <DomNode>(); DomNode[] copies = DomNode.Copy(temp); copies[0].InitializeExtensions(); var nameable = copies[0].As <INameable>(); if (nameable != null) { nameable.Name = uniqueNamer.Name(nameable.Name); } var copyTrans = copies[0].As <ITransformable>(); if (copyTrans != null) { TransformUtils.SetTransform(copyTrans, world); } copyList.Add(copies[0]); } DomNode prefab = new DomNode(Schema.prefabType.Type, Schema.prefabRootElement); var list = prefab.GetChildList(Schema.prefabType.gameObjectChild); Vec3F center = bound.Center; foreach (var gob in copyList) { var trans = gob.As <ITransformable>(); if (trans != null) { trans.Translation = trans.Translation - center; trans.UpdateTransform(); } var node = gob.As <DomNode>(); if (node != null) { list.Add(node); } } return(prefab); }
private void NameNode(DomNode node, UniqueNamer namer) { // if the name isn't unique, make it so string id = node.GetId(); string unique = namer.Name(id); if (id != unique) { node.SetAttribute(node.Type.IdAttribute, unique); } }
/// <summary> /// Checks all DOM nodes in the subtree for validity</summary> protected override void ValidateSubtree() { UniqueNamer uniqueNamer = new UniqueNamer(m_suffixSeparator); foreach (DomNode node in DomNode.Subtree) { foreach (DomNode child in node.Children) { if (child.Type.IdAttribute != null) { string id = child.GetId(); string uniqueId = uniqueNamer.Name(id); if (id != uniqueId) OnIdCollision(child, uniqueId); } } uniqueNamer.Clear(); } }
void ValidateSubtree(DomNode folder) { var uniqueNamer = new UniqueNamer(); foreach (DomNode node in folder.Subtree) { foreach (DomNode child in node.Children) { if (child.Type.IdAttribute != null) { string id = child.GetId(); string uniqueId = uniqueNamer.Name(id); if (id != uniqueId) { throw new InvalidTransactionException("id collision"); } } } uniqueNamer.Clear(); } }
/// <summary> /// Checks all DOM nodes in the subtree for validity</summary> protected override void ValidateSubtree() { UniqueNamer uniqueNamer = new UniqueNamer(m_suffixSeparator); foreach (DomNode node in DomNode.Subtree) { foreach (DomNode child in node.Children) { if (child.Type.IdAttribute != null) { string id = child.GetId(); string uniqueId = uniqueNamer.Name(id); if (id != uniqueId) { OnIdCollision(child, uniqueId); } } } uniqueNamer.Clear(); } }
/// <summary> /// Performs actions for renamed nodes</summary> /// <param name="renamed">Renamed nodes and old ids</param> protected override void RenameNodes(Dictionary <DomNode, string> renamed) { HashSet <DomNode> parents = new HashSet <DomNode>(); foreach (DomNode node in renamed.Keys) { if (node.Parent != null) { parents.Add(node.Parent); } } UniqueNamer uniqueNamer = new UniqueNamer(m_suffixSeparator); foreach (DomNode parent in parents) { // first, initialize namer with the names of the children whose names haven't changed foreach (DomNode child in parent.Children) { if (child.Type.IdAttribute != null && !renamed.ContainsKey(child)) { string id = child.GetId(); uniqueNamer.Name(id); } } // now, generate unique ids for the added children foreach (DomNode child in parent.Children) { if (child.Type.IdAttribute != null && renamed.ContainsKey(child)) { NameNode(child, uniqueNamer); } } uniqueNamer.Clear(); } }
/// <summary> /// Performs actions for added nodes</summary> /// <param name="added">Added nodes</param> /// <param name="renamed">Renamed nodes and old ids</param> protected override void AddNodes(HashSet <DomNode> added, Dictionary <DomNode, string> renamed) { HashSet <DomNode> parents = new HashSet <DomNode>(); foreach (DomNode node in added) { renamed.Remove(node); parents.Add(node.Parent); } UniqueNamer uniqueNamer = new UniqueNamer(m_suffixSeparator); foreach (DomNode parent in parents) { // first, initialize namer with the names of the pre-existing children foreach (DomNode child in parent.Children) { if (child.Type.IdAttribute != null && !added.Contains(child)) { string id = child.GetId(); uniqueNamer.Name(id); } } // now, generate unique ids for the added children foreach (DomNode child in parent.Children) { if (child.Type.IdAttribute != null && added.Contains(child)) { NameNode(child, uniqueNamer); } } uniqueNamer.Clear(); } }
/// <summary> /// Performs actions for added nodes</summary> /// <param name="added">Added nodes</param> /// <param name="renamed">Renamed nodes and old ids</param> protected override void AddNodes(HashSet<DomNode> added, Dictionary<DomNode, string> renamed) { HashSet<DomNode> parents = new HashSet<DomNode>(); foreach (DomNode node in added) { renamed.Remove(node); parents.Add(node.Parent); } UniqueNamer uniqueNamer = new UniqueNamer(m_suffixSeparator); foreach (DomNode parent in parents) { // first, initialize namer with the names of the pre-existing children foreach (DomNode child in parent.Children) { if (child.Type.IdAttribute != null && !added.Contains(child)) { string id = child.GetId(); uniqueNamer.Name(id); } } // now, generate unique ids for the added children foreach (DomNode child in parent.Children) { if (child.Type.IdAttribute != null && added.Contains(child)) { NameNode(child, uniqueNamer); } } uniqueNamer.Clear(); } }
private void NameNode(DomNode node, UniqueNamer namer) { // if the name isn't unique, make it so string id = node.GetId(); string unique = namer.Name(id); if (id != unique) { node.SetAttribute(node.Type.IdAttribute, unique); } }
/// <summary> /// Performs custom actions after an attribute in the DOM node subtree changed</summary> /// <param name="sender">Sender (root DOM node)</param> /// <param name="e">Attribute change event args</param> protected override void OnAttributeChanged(object sender, AttributeEventArgs e) { if (Validating && !m_undoingOrRedoing) { if (e.DomNode.Parent.Is<Group>() && e.AttributeInfo == ElementLabelAttribute) { var subGraph = e.DomNode.Parent.Cast<Group>(); if (e.DomNode.Is<Element>()) { // the name of a sub-node has changed, needs to update group pin names that are not manually set SyncGroupPinNamesFromModuleName(subGraph, e.DomNode); } } else if (e.DomNode.Is<GroupPin>() && e.AttributeInfo == PinNameAttributeAttribute) { if (e.DomNode.Parent != null) { var subGraph = e.DomNode.Parent.Cast<Group>(); // ensure group pin names are unique at local level UniqueNamer uniqueName = new UniqueNamer(); GroupPin childGrpPin = e.DomNode.Cast<GroupPin>(); foreach (var pin in subGraph.Inputs) { var grpPin = pin.Cast<GroupPin>(); if (grpPin != childGrpPin) uniqueName.Name(grpPin.Name); } foreach (var pin in subGraph.Outputs) { var grpPin = pin.Cast<GroupPin>(); if (grpPin != childGrpPin) uniqueName.Name(grpPin.Name); } string unique = uniqueName.Name(childGrpPin.Name); if (unique != childGrpPin.Name) childGrpPin.Name = unique; // try to reset IsDefaultName childGrpPin.IsDefaultName = childGrpPin.Name == childGrpPin.DefaultName(childGrpPin.IsInputSide); UpdateParentGroupPinName(childGrpPin.IsInputSide, childGrpPin); } } } base.OnAttributeChanged(sender,e); }
/// <summary> /// Performs actions for renamed nodes</summary> /// <param name="renamed">Renamed nodes and old ids</param> protected override void RenameNodes(Dictionary<DomNode, string> renamed) { HashSet<DomNode> parents = new HashSet<DomNode>(); foreach (DomNode node in renamed.Keys) parents.Add(node.Parent); UniqueNamer uniqueNamer = new UniqueNamer(m_suffixSeparator); foreach (DomNode parent in parents) { // first, initialize namer with the names of the children whose names haven't changed foreach (DomNode child in parent.Children) { if (child.Type.IdAttribute != null && !renamed.ContainsKey(child)) { string id = child.GetId(); uniqueNamer.Name(id); } } // now, generate unique ids for the added children foreach (DomNode child in parent.Children) { if (child.Type.IdAttribute != null && renamed.ContainsKey(child)) { NameNode(child, uniqueNamer); } } uniqueNamer.Clear(); } }
/// <summary> /// Open or create new document. /// It opens if the file exist otherwise it will creates new document /// </summary> public static GameDocument OpenOrCreate(Uri uri, SchemaLoader schemaLoader) { if (!uri.IsAbsoluteUri) { return(null); } var docRegistry = Globals.MEFContainer.GetExportedValue <GameDocumentRegistry>(); GameDocument document = docRegistry.FindDocument(uri) as GameDocument; if (document != null) { return(document); } string filePath = uri.LocalPath; DomNode rootNode = null; if (File.Exists(filePath)) { // read existing document using custom dom XML reader using (FileStream stream = File.OpenRead(filePath)) { var reader = new CustomDomXmlReader(Globals.ResourceRoot, schemaLoader); rootNode = reader.Read(stream, uri); } } else { // create new document by creating a Dom node of the root type defined by the schema rootNode = new DomNode(Schema.gameType.Type, Schema.gameRootElement); rootNode.SetAttribute(Schema.gameType.nameAttribute, "Game".Localize()); } GameObjectFolder rootFolder = Adapters.As <GameObjectFolder>(rootNode.GetChild(Schema.gameType.gameObjectFolderChild)); if (rootFolder == null) { // create the game object folder rootFolder = (GameObjectFolder)GameObjectFolder.Create(); rootFolder.Name = "GameObjects".Localize("this is the name of a folder in the project lister"); rootNode.SetChild(Schema.gameType.gameObjectFolderChild, rootFolder.DomNode); } // create bookmarks DomNode bookmarks = rootNode.GetChild(Schema.gameType.bookmarksChild); if (bookmarks == null) { bookmarks = new DomNode(Schema.bookmarksType.Type); rootNode.SetChild(Schema.gameType.bookmarksChild, bookmarks); } DomNode layersNode = rootNode.GetChild(Schema.gameType.layersChild); if (layersNode == null) { layersNode = new DomNode(Schema.layersType.Type); rootNode.SetChild(Schema.gameType.layersChild, layersNode); } // Create the grid DomNode gridNode = rootNode.GetChild(Schema.gameType.gridChild); if (gridNode == null) { gridNode = new DomNode(Schema.gridType.Type); rootNode.SetChild(Schema.gameType.gridChild, gridNode); } document = rootNode.As <GameDocument>(); document.Uri = uri; // Initialize Dom extensions now that the data is complete rootNode.InitializeExtensions(); docRegistry.Add(document); UniqueNamer uniqueNamer = new UniqueNamer('_'); foreach (DomNode node in rootNode.Subtree) { if (node.Type.IdAttribute != null) { uniqueNamer.Name(node.GetId()); } } // sync all the prefab instances DomNode folderNode = document.RootGameObjectFolder.As <DomNode>(); foreach (DomNode node in folderNode.Subtree) { PrefabInstance prefab = node.As <PrefabInstance>(); if (prefab == null) { continue; } prefab.Resolve(uniqueNamer); } if (ResolveOnLoad) { // resovle all the game references. foreach (var subGame in document.GetChildList <GameReference>(Schema.gameType.gameReferenceChild)) { subGame.Resolve(); } } document.Dirty = false; return(document); }
public void Resolve(UniqueNamer namer) { try { m_updating = true; Uri resUri = GetAttribute <Uri>(Schema.prefabInstanceType.prefabRefAttribute); if (resUri != null) { m_prefab = Globals.ResourceService.Load(resUri) as IPrefab; } if (m_prefab == null) { return; } // update name and uri if (resUri == null) { SetAttribute(Schema.prefabInstanceType.prefabRefAttribute, m_prefab.Uri); } // Remove the children that are stored within this group (these remain in the file // so that they are used when the resolve fails) var childrenCopy = new List <DomNode>(base.Objects.AsIEnumerable <DomNode>()); foreach (var c in childrenCopy) { c.RemoveFromParent(); } // Create new children from the prefab, applying the overriden attributes as we go DomNode[] gobs = DomNode.Copy(m_prefab.GameObjects.AsIEnumerable <DomNode>()); HashSet <string> gobIds = new HashSet <string>(); for (int c = 0; c < gobs.Length; ++c) { var gobNode = gobs[c]; gobNode.InitializeExtensions(); var name = GetName(gobNode, c); m_intsToOriginal.Add(gobNode, name); gobIds.Add(name); ObjectOverride objectOverride; m_overridesMap.TryGetValue(name, out objectOverride); updateNode(gobNode, objectOverride); if (namer != null) { var nameable = gobNode.As <INameable>(); if (nameable != null) { nameable.Name = namer.Name(nameable.Name); } } AddChild(gobNode); } // cleanup m_overridesmap List <string> overrideIds = new List <string>(m_overridesMap.Keys); foreach (string id in overrideIds) { if (!gobIds.Contains(id)) { ObjectOverride objectOverride = m_overridesMap[id]; objectOverride.DomNode.RemoveFromParent(); m_overridesMap.Remove(id); m_overrideList.Remove(objectOverride); } } } finally { m_updating = false; } }
/// <summary> /// Performs custom actions after an attribute in the DOM node subtree changed</summary> /// <param name="sender">Sender (root DOM node)</param> /// <param name="e">Attribute change event args</param> protected override void OnAttributeChanged(object sender, AttributeEventArgs e) { if (Validating && !m_undoingOrRedoing) { if (e.DomNode.Parent.Is<Group>() && e.AttributeInfo == ElementLabelAttribute) { var subGraph = e.DomNode.Parent.Cast<Group>(); if (e.DomNode.Is<Element>()) { // the name of a sub-node has changed, needs to update group pin names that are not manually set SyncGroupPinNamesFromModuleName(subGraph, e.DomNode); } } else if (e.DomNode.Is<GroupPin>() && e.AttributeInfo == PinNameAttributeAttribute) { if (e.DomNode.Parent != null) { var subGraph = e.DomNode.Parent.Cast<Group>(); // ensure group pin names are unique at local level UniqueNamer uniqueName = new UniqueNamer(); GroupPin childGrpPin = e.DomNode.Cast<GroupPin>(); foreach (var grpPin in subGraph.InputGroupPins) { if (grpPin != childGrpPin) uniqueName.Name(grpPin.Name); } foreach (var grpPin in subGraph.OutputGroupPins) { if (grpPin != childGrpPin) uniqueName.Name(grpPin.Name); } string unique = uniqueName.Name(childGrpPin.Name); if (unique != childGrpPin.Name) childGrpPin.Name = unique; // Reset IsDefaultName. Ignore the suffix because there are typically multiple // circuit elements in a group and the child group pin doesn't know about // our unique namer. string defaultName = childGrpPin.DefaultName(childGrpPin.IsInputSide); string ourRoot; int ourSuffix; uniqueName.Parse(unique, out ourRoot, out ourSuffix); childGrpPin.IsDefaultName = defaultName == ourRoot; UpdateParentGroupPinName(childGrpPin.IsInputSide, childGrpPin); } } } base.OnAttributeChanged(sender,e); }
public void Resolve(UniqueNamer namer) { try { m_updating = true; Uri resUri = GetAttribute <Uri>(Schema.prefabInstanceType.prefabRefAttribute); if (resUri != null) { m_prefab = Globals.ResourceService.Load(resUri) as IPrefab; } if (m_prefab == null) { return; } // update name and uri if (resUri == null) { SetAttribute(Schema.prefabInstanceType.prefabRefAttribute, m_prefab.Uri); } IGameObjectGroup gobgroup = DomNode.As <IGameObjectGroup>(); if (string.IsNullOrWhiteSpace(gobgroup.Name)) { gobgroup.Name = "PrefabInst_" + m_prefab.Name; } DomNode[] gobs = DomNode.Copy(m_prefab.GameObjects.AsIEnumerable <DomNode>()); HashSet <string> gobIds = new HashSet <string>(); gobgroup.GameObjects.Clear(); foreach (var gobNode in gobs) { gobNode.InitializeExtensions(); IGameObject gob = gobNode.As <IGameObject>(); m_intsToOriginal.Add(gobNode, gob.Name); gobIds.Add(gob.Name); ObjectOverride objectOverride; m_overridesMap.TryGetValue(gob.Name, out objectOverride); updateNode(gobNode, objectOverride); string name = gob.Name; if (namer != null) { gob.Name = namer.Name(gob.Name); } gobgroup.GameObjects.Add(gob); } // cleanup m_overridesmap List <string> overrideIds = new List <string>(m_overridesMap.Keys); foreach (string id in overrideIds) { if (!gobIds.Contains(id)) { ObjectOverride objectOverride = m_overridesMap[id]; m_overridesMap.Remove(id); m_overrideList.Remove(objectOverride); } } } finally { m_updating = false; } }