- Lazy Extensions for Faster Startup Time
- Glossary
- Degrees of Lazy Behaviors
- Lazy.xml Reference
- Lazy.xml Use Case Examples
- Complete Example
- FAQ
- Tweaking Lazy Threshold During Development
Lazy Extensions for Faster Startup Time
We have introduced a lazy-load Extensions startup system for CET, in which the initialization of an extension is delayed until it is needed.
Some key points:
- UltraLazyExtensions does not load or compile any extension code at startup.
- All the information that is needed at startup is stored in an XML configuration file called lazy.xml, which is placed alongside the extension.xml.
- The extension will wake up in the following situations:
- if the toolbox is clicked
- if another dependent extension is activated
- an action is performed in which a trigger is defined
- load a drawing that contains snappers from that extension
- other situations mentioned in the below sections
- Renaming lazy.xml to notlazy.xml will result in the extension no longer be lazy, however, the startup behaviors like toolboxes and quickbar configs will still be built according to the definitions in the notlazy.xml.
Guide on migrating to UltraLazyExtensions: MigrateToUltraLazyExtension
Glossary
Lazy : A loading strategy to delay the initialization of an extension until it is needed, using the information in lazy.xml for startup behaviors.
Snooze : The state in which the Extension is turned on but hasn't been initialized by the lazy system.
Unsnooze / Wake : The act of activating the Extension to actually load the library or compile the code of the extension.
Degrees of Lazy Behaviors
This section illustrates what will happen in a few common scenarios:
- For extensions not inheriting from UltraLazyExtension/AdvancedToolboxExtension, but from other classes such as CodeExtension
- Does not have lazy.xml - previous behavior is retained
- Have lazy.xml - the extension will be lazy-loaded according to lazy.xml
- For extensions inheriting from UltraLazyExtension/AdvancedToolboxExtension:
- Has a lazy.xml - the extension will be lazy-loaded according to lazy.xml
- Has a notlazy.xml - the extension will not be lazy-loaded, however all the startup behaviors (e.g. toolboxes) will still be loaded as defined in the notlazy.xml
- Does not have either xml - does not work
Lazy.xml Reference
Lazy.xml is used to define the information needed at startup and its behaviors, with root tag <lazy-extension-info>.
Lazy.xml structure reference:
- <main>
- attribute 'id' : Defines the package ID of the extension
- <quickBar> : Defines a TBPredefinedConfig for the Component Tab Quick Bar
- <id> : An custom identifier for the TBPredefinedConfig
- <label> : Display text for the TBPredefinedConfig
- <toolboxes> : Defines toolboxes
- <toolbox> : Defines a toolbox
- <package> : Package containing the toolbox function
- <function> : The name of the toolbox function
- <label> : Display text of the toolbox card
- <parent> : Grouping parent for collapsing toolbox cards
- <sortKey> : Sorting key for toolbox ordering
- <configId> : Which TBPredefinedConfig does it belong to?
- <visibility> : Use the value 'developMode' to make it visible in DEV only
- <channels> : Defines all the channels this toolbox is visible to
- <channel> : Name of the channel defined in MyConfigura with access to this toolbox
- <toolbox> : Defines a toolbox
- <triggers>
- <trigger> : Defines a trigger
- attribute id : Key of the trigger to be used with triggerLazyExtensions(key)
- <trigger> : Defines a trigger
- <keycodes>
- <keycode> : Defines a shortcut key registration at startup
- attribute id : Identifier of the shortcut
- attribute category : Category/Menu of the shortcut
- attribute key : The key press needed for the shortcut [A-Z0-9]
- attribute ctrl : Modifier Ctrl
- attribute alt : Modifier Alt
- attribute shift : Modifier Shift
- <keycode> : Defines a shortcut key registration at startup
- <resources>
- <resource> : Defines the resource files needed for toolbox card display labels
- attribute filename : File name of the RS file
- attribute pkg : Package containing the RS file
- attribute next : Next package to look for the RS entry if not found
- <resource> : Defines the resource files needed for toolbox card display labels
Lazy.xml Use Case Examples
Minimal
This is the minimal lazy.xml to make an extension lazy.
<?xml version="1.0" encoding="iso-8859-1"?> <lazy-extension-info> <main id="custom.developer" /> </lazy-extension-info>
Single Toolbox Extension
This is an example of a lazy.xml file for an Extension with a single toolbox. When the user clicks that toolbox icon, CET Designer will build the toolbox by calling the "stairsLibrary" function. The parent defines how it should be grouped in the "Component Tabs Configurator".
To define a toolbox with:
- Package: custom.accessories.human
- Library function name: stdHumanLibrary
- Label: Humans (Note: Omit this if the label should be retrieved from rs files).
- Grouping parent: cet.accessories;dummy (Note: Will not create the parent container if it does not exist).
- Sorting key: custom.accessories.human
- Predefined toolbox key: std@predefined
<toolboxes> <toolbox> <package>custom.accessories.human</package> <function>stdHumanLibrary</function> <label>Humans</label> <parent>cet.accessories;dummy</parent> <sortKey>cet.accessories.human</sortKey> <configId>std@predefined</configId> </toolbox> </toolboxes>
Localized Toolbox Extension
This is the same toolbox, but now it will try to find the tooltip for the toolbox in the .rs file.
<?xml version="1.0" encoding="iso-8859-1"?> <lazy-extension-info> <main id="custom.accessories.human" /> <toolboxes> <toolbox> <package>custom.accessories.human</package> <function>stdHumanLibrary</function> <!-- FORCE TRANSLATION! <label>Humans</label> --> <parent>cet.accessories;dummy</parent> <sortKey>cet.accessories.human</sortKey> <configId>std@predefined</configId> </toolbox> </toolboxes> <resources> <!-- if we need to load resources early (flap name lookup). --> <resource filename="human.rs" next="cm.std" /> </resources> </lazy-extension-info>
Multiple Toolboxes
You can define multiple toolboxes for an extension.
<?xml version="1.0" encoding="iso-8859-1"?> <lazy-extension-info> <main id="custom.accessories.stairs" /> <toolboxes> <toolbox> <package>custom.accessories.stairs</package> <function>stairsLibrary</function> <!-- FORCE TRANSLATION! <label>Commercial Stairs</label> --> <parent>cet.buildings;dummy</parent> <sortKey>custom.accessories.stairs#000</sortKey> <configId>std@predefined</configId> </toolbox> <toolbox> <package>custom.accessories.stairs.industrialStairs</package> <function>indStairsLibrary</function> <!-- FORCE TRANSLATION! <label>Industrial Stairs</label> --> <parent>cet.buildings;dummy</parent> <sortKey>custom.accessories.stairs#001</sortKey> <configId>std@predefined</configId> </toolbox> </toolboxes> <resources> <!-- if we need to load resources early (flap name lookup). --> <resource filename="stairs.rs" /> <resource filename="indStairs.rs" pkg="custom.accessories.stairs.industrialStairs" next="custom.accessories.stairs" /> <resource filename="standards.rs" pkg="custom.accessories.stairs.standards" next="custom.accessories.stairs" /> </resources> </lazy-extension-info>
Toolbox Visibility
For toolboxes that are only visible when the user is in a specific channel, or when CET Designer is in developer mode. Channels are assigned to users through MyConfigura.
<toolbox> <package>custom.qaTools</package> <function>hiddenLibrary</function> <label>Hidden Library</label> <sortKey>cet.extensions.qa#9999</sortKey> <configId>custom.dev-all@predefined</configId> <visibility>developMode</visibility> <channels> <channel>custom.qaTools:custom:showHiddenToolbox</channel> </channels> </toolbox>
Component Tab Configuration
For defining component tab configuration. Should only be defined once per group in the "parent" extension. The <id> field is used to determine the members of the configuration by comparing with <toolboxes>/<toolbox>/<configId> of other extensions.
<?xml version="1.0" encoding="iso-8859-1"?> <lazy-extension-info> <main id="custom.developer" /> <quickBar> <id>custom.dev-all@predefined</id> <label>CET Developers</label> </quickBar> </lazy-extension-info>
Triggers
Sometimes you might want to activate the extension on certain actions or conditions.
For example, if your extension includes functionality to export the drawing, you want it to be activated if the user clicks "File -> Import & Export -> Export Drawing...". To do so, you need to add a trigger to your lazy.xml
<?xml version="1.0" encoding="iso-8859-1"?> <lazy-extension-info> <main id="custom.sketchUp" /> <triggers> <trigger id="sceneExport" /> </triggers> </lazy-extension-info>
SketchUp will now be activated whenever you call this method in your code:
triggerLazyExtensions("sceneExport");
Keycodes
Keycodes allow you to unsnooze the extension when a shortcut key is used.
<?xml version="1.0" encoding="iso-8859-1"?> <lazy-extension-info> <main id="custom.walkthrough" /> <triggers> <trigger id="toolsMenu" /> </triggers> <keycodes> <keycode id="wtLibrary" category="tools" key="M" ctrl="true" alt="true" /> </keycodes> </lazy-extension-info>
Complete Example
This example is based off a highly modified Stairs Library extension to better illustrate all of the available features of lazy.xml. This example is available in the base/lazy-reference-stairs branch.
<?xml version="1.0" encoding="iso-8859-1"?> <lazy-extension-info> # Extension package ID <main id="custom.accessories.stairs" /> # Define and register a TBPredefinedConfig with id custom.accessories.stairs-all@predefined" and label "Stairs". # Can be omitted if the same id is already registered somewhere else, e.g. in a mini startup Extension or the lazy.xml of a parent extension. <quickBar> <id>custom.accessories.stairs-all@predefined</id> <label>Stairs</label> </quickBar> # More than one toolbox can be defined in the lazy.xml. <toolboxes> # This defines a toolbox: * Package: custom.accessories.stairs * Library function name: stairsLibrary * Label: Commercial Stairs (Note: Omit this if the label should be retrieved from rs files). * Grouping parent: cet.buildings;dummy (Note: Will not create the parent container if it does not exist). * Sorting key: custom.accessories.stairs#000 * Predefined toolbox key: custom.accessories.stairs-all@predefined <toolbox> <package>custom.accessories.stairs</package> <function>stairsLibrary</function> <label>Commercial Stairs</label> <parent>cet.buildings;dummy</parent> <sortKey>custom.accessories.stairs#000</sortKey> <configId>custom.accessories.stairs-all@predefined</configId> </toolbox> <toolbox> <package>custom.accessories.stairs.industrialStairs</package> <function>indStairsLibrary</function> <label>Industrial Stairs</label> <parent>cet.buildings;dummy</parent> <sortKey>custom.accessories.stairs#001</sortKey> <configId>custom.accessories.stairs-all@predefined</configId> </toolbox> <toolbox> <package>custom.accessories.stairs</package> <function>devLibrary</function> <label>Dev Stairs</label> <parent>cet.buildings;dummy</parent> <sortKey>custom.accessories.stairs#002</sortKey> <configId>custom.accessories.stairs-all@predefined</configId> # Make a toolbox visible in developMode only <visibility>developMode</visibility> </toolbox> <toolbox> <package>custom.accessories.stairs</package> <function>hiddenLibrary</function> <label>Hidden Stairs</label> <parent>cet.buildings;dummy</parent> <sortKey>custom.accessories.stairs#003</sortKey> <configId>custom.accessories.stairs-all@predefined</configId> <visibility>developMode</visibility> # Make a toolbox visible only if subscribed to a channel <channels> <channel>custom.accessories.stairs:custom:showHiddenToolbox</channel> </channels> </toolbox> </toolboxes> # Allow this extension to be woken up by calling via cm.extension.ultraLazy.triggerlazyExtensions("stairs") <triggers> <trigger id="stairs" /> </triggers> # Allow this extension to be woken up through the shortcut CTRL+ALT+SHIFT+S <keycodes> <keycode id="stairsLibrary" category="tools" key="S" ctrl="true" alt="true" shift="true" /> </keycodes> # Resource files needed for toolbox labels if not using <label> in <toolbox> <resources> <resource filename="stairs.rs" /> <resource filename="indStairs.rs" pkg="custom.accessories.stairs.industrialStairs" next="custom.accessories.stairs" /> <resource filename="standards.rs" pkg="custom.accessories.stairs.standards" next="custom.accessories.stairs" /> </resources> </lazy-extension-info>
FAQ
Q: What happens if I rename lazy.xml to notlazy.xml?
A: The extension will not be lazy, however, your toolbox will still be built according to the definitions in notlazy.xml.
Q: My extension is snoozing even though it's not extending from UltraLazyExtension!
A: As long as you have lazy.xml for that extension, it will become lazy.
Q: I get warnings like this: Warning! CollabExtension should be converted to UltraLazyExtension or it will CRASH in release. Please refer to the migration guide.
A: You need to migrate your extensions (that inherits SimpleCatalogExtension or MultiCatalogExtension), to instead inherit from UltraLazyExtension. See the guide on migrating to UltraLazyExtensions: MigrateToUltraLazyExtension
Tweaking Lazy Threshold During Development
How lazy the system should be, is a preference. Some developers like everything to startup as fast as possible, others might prefer the startup to be slightly longer, as long as they don't get those dialogs showing every time they click on a toolbox. If you want it to be less lazy, just specify your preference here:
base/cm/extension/ultraLazy/header.cm /** * Threshold */ package timespan patienceThreshold() { if (developMode) return timespan(); return 120s; }
In release mode, the default is 120 seconds, meaning that for most users all extensions will start up fully. Hence, only if you have a huge amount of extensions installed, that some of them will be snoozing.
Comments
0 comments
Please sign in to leave a comment.