SonyWWS / ATF

Authoring Tools Framework (ATF) is a set of C#/.NET components for making tools on Windows. ATF has been in continuous development in Sony Computer Entertainment's (SCE) Worldwide Studios central tools group since early 2005. ATF has been used by most SCE first party studios to make many custom tools such as Naughty Dog’s level editor and shader editor for The Last of Us, Guerrilla Games’ sequence editor for Killzone games (including the Killzone: Shadow Fall PS4 launch title), an animation blending tool at Santa Monica Studio, a level editor at Bend Studio, a visual state machine editor for Quantic Dream, sound editing tools, and many others.
Apache License 2.0
1.89k stars 262 forks source link

Generating a DomNode with a unique ID and undo/redo #25

Closed vkashkash closed 9 years ago

vkashkash commented 9 years ago

Hello,

I am trying to generate a DomNode by using a context menu on a group, and I am having trouble with generating a unique ID.

First Method:

This method creates an extra node with a unique ID and leaves my original node with the default ID. This method also adds my transaction to the History (although I am uncertain how to implement undo/redo at the moment).

Second Method:

CategoryUniqueIdValidator uniqueIdValidator = childNode.GetRoot().Cast(); uniqueIdValidator.NameNode(childNode);

This method does give a unique name and keeps my child node with the correct properties; however, it does not show up in the History (which I guess means it cannot use undo/redo). Also, this method requires me to make NameNode public.

Is there a way to get the unique ID along with the History :)

Thanks.

jhshen commented 9 years ago

For the first method, I am not sure there is a bug here.

I assume instancingContext is a subclass of ATF's CircuitEditingContext here. CircuitEditingContext.Insert() actually does not insert the passed-in objects directly; it makes a deep copy of the passed-in objects first via DomNode.Copy, then inserts those COPIED DomNodes into the Dom tree. Undo/redo is automatically supported for DOM tree editings that are wrapped in a transaction; usually you don't need to write any code for undo/redo to work.

The unique naming mechanism is kicked in near the end of transaction, and it will check & fix name uniqueness only for those DomNodes that are in the (document) Dom tree, that's why the extra nodes( ie. copied nodes) have unique names because they are the nodes inserted to the dom tree. It seems your original node is not linked into the Dom tree. Perhaps you create a DomNode from scratch, where its parent is not set, so it is a dangling node. If you pass this node to Insert() method, this original node will be cloned to the extra node. But since the original node is not linked into the dom tree, it's name remains to be the default value.

jhshen commented 9 years ago

For the second method, I don't see the necessity to increase the accessibility of CategoryUniqueIdValidator.NameNode(), which is private now. NameNode() is called AddNodes(), the latter is in turned called OnEnding() when a transaction is ending. Both UniqueIdValidator & CategoryUniqueIdValidator , once set up, automatically correct names at the end of a transaction. If you need explicitly call NameNode(), that means you are likely adding DomNode outside a transaction, which is very rare, and lost undo/redo for any Dom edits outside a transaction .

jhshen commented 9 years ago

Typical code snippet to warp you dom edits inside a transaction: var transactionContext = contextRegistry.ActiveContext.As(); transactionContext.DoTransaction(() => { your code of inserting dom node}

vkashkash commented 9 years ago

The issue I had was caused by calling my custom "insert" (outside of DoTransaction) and then calling instancingContext.Insert in DoTransaction, thus generating two DomNode inserts. After looking at your code snippet, I just called my custom "insert" function in DoTransaction, which fixed the issue. Thanks :)

jhshen commented 9 years ago

Cool! I think the reason that we make a copy first before insert, is that sometimes copy/paste may come from clipboard, or even another document. Copy-before-insert makes everything simpler. :-)