Skip to content

Using the DomRecorder Component

Gary edited this page Aug 27, 2014 · 1 revision

Table of Contents

The DomRecorder component records DOM events on the active context and displays them in a list in a window. These logged events can also be retrieved programmatically.

Importing the DomRecorder Component

Because it's a MEF component, it's simple to use DomRecorder. Add it to the TypeCatalog with the other MEF components. For information on how to do this, see How MEF is Used in ATF. The ATF Circuit Editor Sample uses this component.

DomRecorder User Interface

DomRecorder adds a DOM Recorder window to the application, as seen in this figure:

You can select events in the list. Ctrl + click adds to the selection; Shift + click selects a range of events.

The control buttons do the following:

  • Copy All: Copy the text of the selected events to the clipboard.
  • Clear: Clear the list of events.
  • Deep Analysis: Check to get more event information that may indicate problems.
The window contains an ordered list of DOM events in a TreeListView. The columns are:
  • Trans.#: Transaction number, which is -1 if the event is not part of a transaction.
  • Description: Event description, showing information depending on the event. For details, see Events Recorded.
  • Analysis: Description of the event, which is formatted when the Deep Analysis box is checked. For an explanation, see Event Deep Analysis.

Events Recorded

Changes to all DomNode trees and transaction events are recorded. Appropriate information is recorded for the events. The event examples in the table below are from the ATF Circuit Editor Sample.

Event Log format
DomNode.DiagnosticAttributeChanged [<Modified DomNode>; id <DomNode ID or hash code>]: set [<Attribute name>] from [<Old value>] to [<New value>].
For example:
[0x3717a0e, http://sony.com/gametech/circuits/1_0:buttonType; id Button_3]: set [name] from [] to [Button_3]
DomNode.DiagnosticChildInserted [<Child DomNode>; id <Child DomNode ID or hash code>]: add to [<Parent DomNode>; id <Parent DomNode ID or hash code>] at index <index>.
For example:
[0x3717a0e, http://sony.com/gametech/circuits/1_0:buttonType; id Button_3]:
add to [0x15b0aa4, http://sony.com/gametech/circuits/1_0:circuitDocumentType; id 15B0AA4] at index 0
DomNode.DiagnosticChildRemoved [<Child DomNode>; id <Child DomNode ID or hash code>]:
remove from [<Parent DomNode>; id <Parent DomNode ID or hash code>] at index <index>.
For example:
[0x1a23c51, http://sony.com/gametech/circuits/1_0:subCircuitInstanceType; id MasterInstance_2]:
remove from [0x15b0aa4, http://sony.com/gametech/circuits/1_0:circuitDocumentType id 15B0AA4] at index 6
IValidationContext.Beginning Transaction began : [<Transaction name>].
For example: Transaction began : [Drag and Drop]
IValidationContext.Cancelled Transaction cancelled : [<Transaction name>].
For example: Transaction cancelled : [Delete]
IValidationContext.Ended Transaction ended : [<Transaction name>].
For example: Transaction ended : [Drag Items]

DomRecorder API

You can access the log created by a DomRecorder object through its properties and methods:

  • IEnumerable<string> GetLogEvents(int maxEvents): Get the most recent maxEvents log events, from oldest to newest.
  • int NumLogEvents: Get the number of events in the log.
  • void Clear(): Clear all the log data and refresh the Control.
  • IDocumentRegistry DocumentRegistry: Get or set the optional document registry. If present, when a document is closed, all the DOM event data is cleared to prevent memory leaks.
  • IContextRegistry ContextRegistry: Get or set the context registry to be used to automatically find the root DomNode and validation context. This is optional and can be null.
  • IValidationContext ValidationContext: Gets or sets the validation context that is used to record when transactions begin and end. This is optional and can be null. It is set automatically if the context registry raises the ActiveContextChanged event, and the new context can be adapted to IValidationContext.

Event Deep Analysis

Each event can have zero or more listeners, that is, objects that subscribe to the event and have event handlers that are called when the event occurs. For instance, DOM adapters defined for application data types often listen to DOM change events. DOM adapters may well be the bulk of listeners.

When the Deep Analysis box is checked, DomRecorder analyzes the listeners for DomNode events. It reports the following information and possible problems for each event:

  • "# of listeners": Number of event listeners. If this number decreases, it could indicate that changes are not being observed that should be. If this number is higher than expected, perhaps unwanted listeners are degrading performance.
  • "DUPLICATE LISTENER: <event></event> on <type></type>". Are there any duplicate listeners? That is, is the same event handler being called from two different objects, indicating a duplicate effort is occurring? This could happen if there were two instances of the same listener. This reports only the last duplicate found; there may be more than one.
  • "# of IHistoryContext": Number of listeners that implement IHistoryContext. If there are no such listeners, the change is not being recorded for undo/redo.
  • "# recording": Number of listeners deriving from the ATF class HistoryContext that are recording changes. If recording is not enabled, then the change is not automatically added to an undo/redo command history stack. This isn't necessarily an error. For example, the change could be temporary, such as when dragging a circuit element on a canvas. Or perhaps client code manually adds a command to CommandHistory.
Deep analysis can be time-consuming, but can be useful when debugging event handling.

Here is a sample analysis message:

# of listeners: 13. DUPLICATE LISTENER: DomNode_ChildInserted on Sce.Atf.Dom.Observer. # of IHistoryContext: 2. # recording: 2

Because it is time-consuming, Deep Analysis is disabled by default. If you need to analyze events that occur during application start up, you can modify the m_analysisEnabled field to set its original value to true:

private bool m_analysisEnabled = true;

In general, you do not need to do this. Most listeners are probably DOM adapters, and they do not start listening until after they have all been initialized, which does not occur until the application has fully initialized.

DomRecorder Example

The ATF Circuit Editor Sample imports DomRecorder. The illustration shows an opened circuit file and the DOM events recorded and displayed in the DOM Recorder window:

None of these events are part of a transaction, and so no transaction events are recorded; the Trans.# column is all -1. When an And gate is dragged onto the circuit, events enclosed by a transaction named "Drag and Drop" are recorded:

Note that the transaction number is now 1. Four events are bounded by the transaction that all refer to the same added DomNode:

  1. The "andType" DomNode's "name" attribute is set to "And":
    [0x6bcd0c, http://sony.com/gametech/circuits/1_0:andType; id And]: set [name] from [] to [And].
    # of listeners: 0
  2. The DomNode is added as a child to another DomNode of "circuitDocumentType" at index 12:
    [0x6bcd0c, http://sony.com/gametech/circuits/1_0:andType; id And]: add to 
    [0x980051, http://sony.com/gametech/circuits/1_0:circuitDocumentType; id 980051] at index 12.
    # of listeners: 13. # of IHistoryContext: 2. # recording: 2
  3. The DomNode's "x" attribute is set to "-64" to reflect the dragged And gate's canvas x-coordinate:
    [0x6bcd0c, http://sony.com/gametech/circuits/1_0:andType; id And]: set [x] from [0] to [-64]. 
    # of listeners: 14. # of IHistoryContext: 2. # recording: 2
  4. The DomNode's "y" attribute is set to "160" to reflect the dragged And gate's canvas y-coordinate:
    [0x6bcd0c, http://sony.com/gametech/circuits/1_0:andType; id And]: set [y] from [0] to [160]. 
    # of listeners: 14. # of IHistoryContext: 2. # recording: 2
According to the Deep Analysis column, there are no event listeners until the DomNode is actually added. Afterwards, there are 14 listeners, two of which derive from HistoryContext and are recording commands on the history stack.

Topics in this section

Clone this wiki locally