Appendix A. Understanding Instantiation

Table of Contents

1. Overview
2. When instances are instantiated
3. How instances are instantiated

1. Overview

The instantiation of LzNode objects such as LzView and LzLayout is a multi-phase procedure, but in general, you do not need to know the details of the instantiation of view objects; they "just work". In rare cases, you will need to understand the details of the process. Parts of the process can be deferred to speed startup of an application.

This chapter assumes you are familar with classes and objects. In the descriptions below, we distinguish between creation, by which we mean storage for the object is allocated and constant properties assigned — a process that cannot be customized — and initialization, by which we mean the instantiation of children and the application of computed attributes, which can be customized (by overriding the init() method). These two processes together are referred to as instantiation.

2. When instances are instantiated

At a high level, the initialization of a LzNode, the calling of its init() method, and sending of the oninit() event is under the control of its initstage attribute, as follows:

immediate

Initialization happens immediately as the last stage of instantiation.

early

Initialization happens right after the view and its children have been created.

normal

Initialization happens when the parent is initialized.

late

Initialization happens during idle time. To check whether the view has been initialized, check the isinited property. Force initialization using the completeInstantiation() method.

defer

Initialization will not happen unless explicitly requested by calling the completeInstantation() method.

3. How instances are instantiated

When a node is instantiated, its attributes are the attributes explicitly given in the object, plus any attributes that the class specifies. Similarly, its children will be the childen explicitly given in the object, plus any children that are specified in the class. The class construct() method is called, with these attributes and the parent view.

The steps happen in the following sequence:

  1. A single dictionary is created which combines the attributes of the instance with the attributes of the class

  2. A single array is created which combines the children of the instance with the children of the class

  3. construct(args, parent) is called. args is a dictionary of your attributes (does not include expressions, such width="${parent.width}"), parent is the lexical parent. This method can only be declared in a class, not in an instance. You can modify the arguments or the parent before calling super.construct.

  4. Any <handler name="..."> for the class or event handlers (e.g. onclick in the tag) for the class are created for the instance

  5. Attributes with when="immediately" values are applied

    1. Attributes with no setters are set

    2. Special LFC attributes are set

      • The name attribute

      • The id attribute

      • Event handlers

      • Event methods

      • The classroot attribute

      • Datapath children are created (datapath set using <datapath xpath="...">)

    3. Attributes with setters (<attribute name="foo" value="0" setter="setfoo(foo)" />). setfoo(0) will be called before initialization and before children are instantiated, but after you have a parent and the attributes mentioned above applied)

  6. createChildren() is called with an array of children with the superclass' children first (deepest first). There are two options for how children are created: synchronously and asynchronously. When whichever method is chosen completes, __LZinstantiationDone will be called on this instance.

    Synchronous creation

    No other code can run until all the children for this instance are created

    intstage="immediate"

    new classname(parent, args, children, false) or any trailing args are omitted, e.g. new classname(parent, args)

    Asynchronous creation

    Children for this instance will be put on the LzInstantiator queue and created later.

    initstage="early"

    initstage="normal"

    Children will be created at high priority

    initstage="late"

    Children will be created at low priority

    intstage="defer"

    Children are not created until completeInstantiation() is called

  7. After the children have been created, initialization will happen if:

    • initstage="early"

    • The instance's immediateparent has already been initialized

    • The instance is the canvas

    • The completeInstantiation() was called

    otherwise initialization will be triggered by this instance's immediateparent being initialized.

  8. Initialization

    1. Resolve references:

      1. $once{...}

      2. $always{...}

      3. <method..." reference="...">

    2. Initialize subviews that are not initstage="late" or initstage="defer"

    3. Call the init() method

    4. Send the oninit event