Harb, can you explain to me the importance/need for @royaleignorecoercion?

Hiedra

-----Mensaje original-----
De: Harbs <harbs.li...@gmail.com> 
Enviado el: jueves, 21 de diciembre de 2023 0:35
Para: Apache Royale Development <dev@royale.apache.org>
Asunto: Re: (royale-asjs) branch develop updated: Added factory for reusing 
data item renderers

FYI, this class had a drastic effect on a tree I was working on. Expanding a 
node went from taking between 1 and 2 seconds to taking about 20ms.

I also committed a number of other performance optimizations relating 
specifically to trees. It’s now possible to create a custom implementation for 
getting the depth of nodes which is very expensive in the built-in method.

Harbs

> On Dec 21, 2023, at 1:31 AM, ha...@apache.org wrote:
> 
> This is an automated email from the ASF dual-hosted git repository.
> 
> harbs pushed a commit to branch develop in repository 
> https://gitbox.apache.org/repos/asf/royale-asjs.git
> 
> 
> The following commit(s) were added to refs/heads/develop by this push:
>     new 4e186b7442 Added factory for reusing data item renderers
> 4e186b7442 is described below
> 
> commit 4e186b7442872764e27f086a3a03863f09c599aa
> Author: Harbs <ha...@in-tools.com>
> AuthorDate: Thu Dec 21 01:31:18 2023 +0200
> 
>    Added factory for reusing data item renderers
> ---
> .../Basic/src/main/resources/basic-manifest.xml    |   1 +
> .../projects/Basic/src/main/royale/BasicClasses.as |   1 +
> .../DataItemRendererFactoryForCollectionView.as    |   2 +
> ...bleDataItemRendererFactoryForCollectionView.as} | 113 
> ++++++---------------
> 4 files changed, 34 insertions(+), 83 deletions(-)
> 
> diff --git 
> a/frameworks/projects/Basic/src/main/resources/basic-manifest.xml 
> b/frameworks/projects/Basic/src/main/resources/basic-manifest.xml
> index dc0d7bfd00..51a682c0e4 100644
> --- a/frameworks/projects/Basic/src/main/resources/basic-manifest.xml
> +++ b/frameworks/projects/Basic/src/main/resources/basic-manifest.xml
> @@ -228,6 +228,7 @@
>     <component id="DynamicUpdateItemRendererForArrayListData" 
> class="org.apache.royale.html.beads.DynamicUpdateItemRendererForArrayListData"/>
>     <component id="DataItemRendererFactoryForHierarchicalData" 
> class="org.apache.royale.html.beads.DataItemRendererFactoryForHierarchicalData"
>  />
>     <component id="DataItemRendererFactoryForCollectionView" 
> class="org.apache.royale.html.beads.DataItemRendererFactoryForCollecti
> onView" />
> +    <component id="ReusableDataItemRendererFactoryForCollectionView" 
> + class="org.apache.royale.html.beads.ReusableDataItemRendererFactoryF
> + orCollectionView" />
>     <component id="SelectionDataItemRendererFactoryForCollectionView" 
> class="org.apache.royale.html.beads.SelectionDataItemRendererFactoryForCollectionView"
>  />
>     <component id="DynamicRemoveAllItemRendererForArrayListData" 
> class="org.apache.royale.html.beads.DynamicRemoveAllItemRendererForArrayListData"
>  />
>     <component id="DynamicRemoveAllByNullItemRendererForArrayListData" 
> class="org.apache.royale.html.beads.DynamicRemoveAllByNullItemRenderer
> ForArrayListData" /> diff --git 
> a/frameworks/projects/Basic/src/main/royale/BasicClasses.as 
> b/frameworks/projects/Basic/src/main/royale/BasicClasses.as
> index f5591dcad6..91a45a7911 100644
> --- a/frameworks/projects/Basic/src/main/royale/BasicClasses.as
> +++ b/frameworks/projects/Basic/src/main/royale/BasicClasses.as
> @@ -245,6 +245,7 @@ internal class BasicClasses
>       import 
> org.apache.royale.html.beads.DataItemRendererFactoryForArrayList; 
> DataItemRendererFactoryForArrayList;
>       import 
> org.apache.royale.html.beads.DataItemRendererFactoryForHierarchicalData; 
> DataItemRendererFactoryForHierarchicalData;
>       import 
> org.apache.royale.html.beads.DataItemRendererFactoryForCollectionView; 
> DataItemRendererFactoryForCollectionView;
> +     import 
> +org.apache.royale.html.beads.ReusableDataItemRendererFactoryForCollec
> +tionView; ReusableDataItemRendererFactoryForCollectionView;
>       import org.apache.royale.html.supportClasses.DataGroup; DataGroup;
>       import org.apache.royale.html.supportClasses.Border; Border;
>       import org.apache.royale.html.supportClasses.Viewport; Viewport; diff 
> --git 
> a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/bea
> ds/DataItemRendererFactoryForCollectionView.as 
> b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/bea
> ds/DataItemRendererFactoryForCollectionView.as
> index de128b771e..07b387c7a0 100644
> --- 
> a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/bea
> ds/DataItemRendererFactoryForCollectionView.as
> +++ b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html
> +++ /beads/DataItemRendererFactoryForCollectionView.as
> @@ -77,6 +77,7 @@ package org.apache.royale.html.beads
>                * @royaleignorecoercion 
> org.apache.royale.collections.ICollectionView
>                * @royaleignorecoercion 
> org.apache.royale.core.IListPresentationModel
>                * @royaleignorecoercion 
> org.apache.royale.core.IIndexedItemRenderer
> +              * @royaleignorecoercion 
> +org.apache.royale.core.IIndexedItemRendererInitializer
>                * @royaleignorecoercion 
> org.apache.royale.core.IStrandWithModelView
>                * @royaleignorecoercion org.apache.royale.html.beads.IListView
>                */
> @@ -152,6 +153,7 @@ package org.apache.royale.html.beads
>                * @private
>                * @royaleignorecoercion 
> org.apache.royale.collections.ICollectionView
>                * @royaleignorecoercion 
> org.apache.royale.core.IIndexedItemRenderer
> +              * @royaleignorecoercion 
> +org.apache.royale.core.IIndexedItemRendererInitializer
>                * @royaleignorecoercion 
> org.apache.royale.core.IStrandWithModelView
>                * @royaleignorecoercion org.apache.royale.html.beads.IListView
>                */
> diff --git 
> a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/bea
> ds/DataItemRendererFactoryForCollectionView.as 
> b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/bea
> ds/ReusableDataItemRendererFactoryForCollectionView.as
> similarity index 58%
> copy from 
> frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads
> /DataItemRendererFactoryForCollectionView.as
> copy to 
> frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads
> /ReusableDataItemRendererFactoryForCollectionView.as
> index de128b771e..d697b26632 100644
> --- 
> a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/bea
> ds/DataItemRendererFactoryForCollectionView.as
> +++ b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html
> +++ /beads/ReusableDataItemRendererFactoryForCollectionView.as
> @@ -18,76 +18,55 @@
> //////////////////////////////////////////////////////////////////////
> //////////
> package org.apache.royale.html.beads
> {
> +     import org.apache.royale.utils.sendStrandEvent;
> +     import org.apache.royale.events.CollectionEvent;
> +     import org.apache.royale.core.IStrandWithModelView;
>       import org.apache.royale.core.IIndexedItemRenderer;
>       import org.apache.royale.core.IIndexedItemRendererInitializer;
>       import org.apache.royale.core.IItemRendererOwnerView;
> -     import org.apache.royale.core.IStrandWithModelView;
> -     import org.apache.royale.events.CollectionEvent;
> -     import org.apache.royale.events.Event;
> -     import org.apache.royale.events.IEventDispatcher;
> -     import org.apache.royale.html.beads.IListView;
> -     import org.apache.royale.utils.sendStrandEvent;
> -     
>       /**
> -      * This class creates itemRenderer instances from the data contained 
> within an ICollectionView
> +      * The ReusableDataItemRendererFactoryForCollectionView class will save 
> removed itemRenderers
> +      * and reuse them when new item renderers are needed. This is useful 
> for large collections
> +      * where creating new item renderers can be expensive. Using this class 
> can drastically
> +      * reduce rendering time at the expense of preventing the unused item 
> renderers from being
> +      * garbage collected.
> +      * 
> +      * In an unscientific test, using this class reduced rendering time by 
> about a factor of 100 in some cases.
> +      * 
> +      * Item renderers must be able to be reused. Resetting the data 
> property must properly reset the state and
> +      * clean any event listeners from the old state.
>        */
> -     public class DataItemRendererFactoryForCollectionView extends 
> DataItemRendererFactoryBase
> +     public class ReusableDataItemRendererFactoryForCollectionView 
> +extends DataItemRendererFactoryForCollectionView
>       {
> -             public function 
> DataItemRendererFactoryForCollectionView(target:Object = null)
> +             public function 
> +ReusableDataItemRendererFactoryForCollectionView(target:Object = 
> +null)
>               {
>                       super(target);
>               }
> -             
> -             /**
> -              * the dataProvider as a dispatcher
> -              */
> -             protected var dped:IEventDispatcher;
> +
> +             private var _unusedRenderers:Array = [];
> 
>               /**
>                * @private
>                * @royaleignorecoercion 
> org.apache.royale.collections.ICollectionView
>                * @royaleignorecoercion 
> org.apache.royale.core.IListPresentationModel
>                * @royaleignorecoercion 
> org.apache.royale.core.IIndexedItemRenderer
> -              * @royaleignorecoercion 
> org.apache.royale.events.IEventDispatcher
> -              */
> -             override protected function 
> dataProviderChangeHandler(event:Event):void
> -             {
> -                     super.dataProviderChangeHandler(event);
> -                     
> -                     if(dped)
> -                     {
> -                             
> dped.removeEventListener(CollectionEvent.ITEM_ADDED, itemAddedHandler);
> -                             
> dped.removeEventListener(CollectionEvent.ITEM_REMOVED, itemRemovedHandler);
> -                             
> dped.removeEventListener(CollectionEvent.ITEM_UPDATED, itemUpdatedHandler);
> -                             dped = null;
> -                     }
> -                     
> -                     if (!dataProviderModel.dataProvider)
> -                             return;
> -                     
> -                     // listen for individual items being added in the 
> future.
> -                     dped = dataProviderModel.dataProvider as 
> IEventDispatcher;
> -                     dped.addEventListener(CollectionEvent.ITEM_ADDED, 
> itemAddedHandler);
> -                     dped.addEventListener(CollectionEvent.ITEM_REMOVED, 
> itemRemovedHandler);
> -                     dped.addEventListener(CollectionEvent.ITEM_UPDATED, 
> itemUpdatedHandler);
> -             }
> -             
> -             /**
> -              * @private
> -              * @royaleignorecoercion 
> org.apache.royale.collections.ICollectionView
> -              * @royaleignorecoercion 
> org.apache.royale.core.IListPresentationModel
> -              * @royaleignorecoercion 
> org.apache.royale.core.IIndexedItemRenderer
> +              * @royaleignorecoercion 
> +org.apache.royale.core.IIndexedItemRendererInitializer
>                * @royaleignorecoercion 
> org.apache.royale.core.IStrandWithModelView
>                * @royaleignorecoercion org.apache.royale.html.beads.IListView
>                */
> -             protected function itemAddedHandler(event:CollectionEvent):void
> +             override protected function 
> +itemAddedHandler(event:CollectionEvent):void
>               {
>                       if(!dataProviderExist)
>                               return;
>                       var view:IListView = (_strand as 
> IStrandWithModelView).view as IListView;
>                       var dataGroup:IItemRendererOwnerView = view.dataGroup;
>                       
> -                     var ir:IIndexedItemRenderer = 
> itemRendererFactory.createItemRenderer() as IIndexedItemRenderer;
> +                     var ir:IIndexedItemRenderer;
> +                     if(_unusedRenderers.length > 0)
> +                             ir = _unusedRenderers.pop();
> +
> +                     else
> +                             ir = itemRendererFactory.createItemRenderer() 
> as 
> +IIndexedItemRenderer;
> 
>                       var data:Object = event.item;
>                       dataGroup.addItemRendererAt(ir, event.index); @@ -108,7 
> +87,8 @@ 
> package org.apache.royale.html.beads
>                       }
>                       
>                       sendStrandEvent(_strand,"itemsCreated");
> -                     sendStrandEvent(_strand,"layoutNeeded");
> +                     // The itemsCreated handler sends layoutNeeded, so no 
> need to do it here.
> +                     // sendStrandEvent(_strand,"layoutNeeded");
>               }
>               
>               /**
> @@ -119,7 +99,7 @@ package org.apache.royale.html.beads
>                * @royaleignorecoercion 
> org.apache.royale.core.IStrandWithModelView
>                * @royaleignorecoercion org.apache.royale.html.beads.IListView
>                */
> -             protected function 
> itemRemovedHandler(event:CollectionEvent):void
> +             override protected function 
> +itemRemovedHandler(event:CollectionEvent):void
>               {
>                       if(!dataProviderExist)
>                               return;
> @@ -130,7 +110,7 @@ package org.apache.royale.html.beads
>                       var ir:IIndexedItemRenderer = 
> dataGroup.getItemRendererAt(event.index) as IIndexedItemRenderer;
>                       if (!ir) return; // may have already been cleaned up, 
> possibly when a tree node closes
>                       dataGroup.removeItemRenderer(ir);
> -                     
> +                     _unusedRenderers.push(ir);
>                       // adjust the itemRenderers' index to adjust for the 
> shift
>                       var n:int = dataGroup.numItemRenderers;
>                       for (var i:int = event.index; i < n; i++) @@ -147,39 
> +127,6 @@ 
> package org.apache.royale.html.beads
> 
>                       sendStrandEvent(_strand,"layoutNeeded");
>               }
> -             
> -             /**
> -              * @private
> -              * @royaleignorecoercion 
> org.apache.royale.collections.ICollectionView
> -              * @royaleignorecoercion 
> org.apache.royale.core.IIndexedItemRenderer
> -              * @royaleignorecoercion 
> org.apache.royale.core.IStrandWithModelView
> -              * @royaleignorecoercion org.apache.royale.html.beads.IListView
> -              */
> -             protected function 
> itemUpdatedHandler(event:CollectionEvent):void
> -             {
> -                     if(!dataProviderExist)
> -                             return;
> -
> -                     var view:IListView = (_strand as 
> IStrandWithModelView).view as IListView;
> -                     var dataGroup:IItemRendererOwnerView = view.dataGroup;
> -                     
> -                     // update the given renderer with (possibly) new 
> information so it can change its
> -                     // appearence or whatever.
> -                     var ir:IIndexedItemRenderer = 
> dataGroup.getItemRendererAt(event.index) as IIndexedItemRenderer;
> -
> -                     var data:Object = event.item;
> -                     (itemRendererInitializer as 
> IIndexedItemRendererInitializer).initializeIndexedItemRenderer(ir, data, 
> event.index);
> -                     ir.data = data;
> -             }
> -
> -             override protected function get dataProviderLength():int
> -             {
> -                     return dataProviderModel.dataProvider.length;
> -             }
> -             
> -             override protected function getItemAt(i:int):Object
> -             {
> -                     return dataProviderModel.dataProvider.getItemAt(i);
> -             }
> +                             
>       }
> }
> \ No newline at end of file
> 

Reply via email to