Hi Harbs,

any of us that are working on Docs now can do this, but I think we need
more explanation about what is all about.
Is important to create a code that works, but is equally important to
explain what is the purpose so we can understand what's the improvement.
And I think this goes for all of us, included me.

Can you explain more about this?
As well give some clues of where s that code located, seems in print, but
nor in Royale?

With all of that then we can plan some docs to expose this.

Thanks! :)

El mar., 4 jun. 2019 a las 14:03, Harbs (<harbs.li...@gmail.com>) escribió:

> I finally got fed up enough with Promises et. al. that I broke down and
> wrote some Async classes which (IMO) are much easier to use.
>
> AsyncTask needs to be subclassed. Here’s an implementation that I’m using
> in my app. If I find some time, I might create some HTTP tasks. I someone
> who’s better at docs than me wants to write something, that would be great.
> ;-)
>
> package com.printui.utils
> {
>   import com.printui.model.vos.FontVO;
>   import com.printui.model.proxies.FontProxy;
>
>   public class LoadFontTask extends AsyncTask
>   {
>     public function LoadFontTask(font:FontVO)
>     {
>       super();
>       this.font = font;
>     }
>     private var font:FontVO;
>     override public function run(data:Object = null):void{
>       var fp:FontProxy =
> ApplicationFacade.getInstance().retrieveProxy(FontProxy.NAME) as FontProxy;
>       fp.loadNow(font,fontLoadDone);
>     }
>     private function fontLoadDone():void{
>       if(font.embedded){
>         complete();
>       } else {
>         fail();
>       }
>     }
>   }
> }
>
> I’m using it like so:
>
>     public function embedFonts(callback:Function):void{
>       if(fontsEmbedded()){
>         callback();
>       } else {
>         var tasks:Array = [];
>         var font:FontVO = getAppliedFont();
>         if(!font.embedded){
>           tasks.push(new LoadFontTask(font));
>         }
>         font = getBulletFont();
>         if(font && !font.embedded){
>           tasks.push(new LoadFontTask(font));
>         }
>         var task:CompoundAsyncTask = new CompoundAsyncTask(tasks);
>         task.done(function(task:AsyncTask):void{
>           if(task.status == "complete"){
>             // we're good
>             callback();
>           } else {
>             // status is "failed" -- not sure what to do...
>           }
>         });
>         task.run();
>       }
>     }
>
>
> > On Jun 4, 2019, at 2:55 PM, 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 edb052c  Added Async tasks
> > edb052c is described below
> >
> > commit edb052cbf2fb1b9db276dff6e4a94ce0a7679f00
> > Author: Harbs <ha...@in-tools.com>
> > AuthorDate: Tue Jun 4 14:55:00 2019 +0300
> >
> >    Added Async tasks
> > ---
> > .../CoreJS/src/main/config/compile-js-config.xml   |   1 +
> > .../Core/src/main/config/compile-swf-config.xml    |   1 +
> > .../Core/src/main/resources/basic-manifest.xml     |   3 +
> > .../projects/Core/src/main/royale/CoreClasses.as   |   3 +
> > .../royale/org/apache/royale/utils/ObjectMap.as    |  12 ++
> > .../org/apache/royale/utils/async/AsyncTask.as     | 180
> +++++++++++++++++++++
> > .../apache/royale/utils/async/CompoundAsyncTask.as | 135 ++++++++++++++++
> > .../royale/utils/async/SequentialAsyncTask.as      |  77 +++++++++
> > 8 files changed, 412 insertions(+)
> >
> > diff --git
> a/frameworks/js/projects/CoreJS/src/main/config/compile-js-config.xml
> b/frameworks/js/projects/CoreJS/src/main/config/compile-js-config.xml
> > index bdc495e..e912e57 100644
> > --- a/frameworks/js/projects/CoreJS/src/main/config/compile-js-config.xml
> > +++ b/frameworks/js/projects/CoreJS/src/main/config/compile-js-config.xml
> > @@ -71,6 +71,7 @@
> >         </source-path>
> >
> >         <warn-no-constructor>false</warn-no-constructor>
> > +        <allow-abstract-classes>true</allow-abstract-classes>
> >
> >         <!-- Use of the instanceof operator. -->
> >         <warn-instance-of-changes>false</warn-instance-of-changes>
> > diff --git
> a/frameworks/projects/Core/src/main/config/compile-swf-config.xml
> b/frameworks/projects/Core/src/main/config/compile-swf-config.xml
> > index ecd4c77..265d4d8 100644
> > --- a/frameworks/projects/Core/src/main/config/compile-swf-config.xml
> > +++ b/frameworks/projects/Core/src/main/config/compile-swf-config.xml
> > @@ -75,6 +75,7 @@
> >         </source-path>
> >
> >         <warn-no-constructor>false</warn-no-constructor>
> > +        <allow-abstract-classes>true</allow-abstract-classes>
> >
> >         <!-- Use of the instanceof operator. -->
> >         <warn-instance-of-changes>false</warn-instance-of-changes>
> > diff --git
> a/frameworks/projects/Core/src/main/resources/basic-manifest.xml
> b/frameworks/projects/Core/src/main/resources/basic-manifest.xml
> > index ae4b7f7..f40d2e4 100644
> > --- a/frameworks/projects/Core/src/main/resources/basic-manifest.xml
> > +++ b/frameworks/projects/Core/src/main/resources/basic-manifest.xml
> > @@ -52,4 +52,7 @@
> >     <component id="StyleChangeNotifier"
> class="org.apache.royale.core.StyleChangeNotifier"/>
> >
> >     <component id="State" class="org.apache.royale.states.State"/>
> > +
> > +    <component id="CompoundAsyncTask"
> class="org.apache.royale.utils.CompoundAsyncTask">
> > +    <component id="SequentialAsyncTask"
> class="org.apache.royale.utils.SequentialAsyncTask">
> > </componentPackage>
> > diff --git a/frameworks/projects/Core/src/main/royale/CoreClasses.as
> b/frameworks/projects/Core/src/main/royale/CoreClasses.as
> > index 678df00..cdd9b25 100644
> > --- a/frameworks/projects/Core/src/main/royale/CoreClasses.as
> > +++ b/frameworks/projects/Core/src/main/royale/CoreClasses.as
> > @@ -308,6 +308,9 @@ internal class CoreClasses
> >       import org.apache.royale.utils.date.addSeconds; addSeconds;
> >       import org.apache.royale.utils.date.addYears; addYears;
> >
> > +     import org.apache.royale.utils.async.CompoundAsyncTask;
> CompoundAsyncTask;
> > +     import org.apache.royale.utils.async.SequentialAsyncTask;
> SequentialAsyncTask;
> > +
> >       import org.apache.royale.utils.css.addDynamicSelector;
> addDynamicSelector;
> >
> >       COMPILE::JS
> > diff --git
> a/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/ObjectMap.as
> b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/ObjectMap.as
> > index d3bd5bc..836b76e 100644
> > ---
> a/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/ObjectMap.as
> > +++
> b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/ObjectMap.as
> > @@ -157,9 +157,21 @@ package org.apache.royale.utils
> >
> >         COMPILE::JS
> >         {
> > +            /**
> > +             *  @royalesuppresspublicvarwarning
> > +             */
> >             public var get:Function = objectGet;
> > +            /**
> > +             *  @royalesuppresspublicvarwarning
> > +             */
> >             public var set:Function = objectSet;
> > +            /**
> > +             *  @royalesuppresspublicvarwarning
> > +             */
> >             public var has:Function = objectHas;
> > +            /**
> > +             *  @royalesuppresspublicvarwarning
> > +             */
> >             public var delete:Function = objectDelete;
> >         }
> >
> > diff --git
> a/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/async/AsyncTask.as
> b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/async/AsyncTask.as
> > new file mode 100644
> > index 0000000..44a31ce
> > --- /dev/null
> > +++
> b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/async/AsyncTask.as
> > @@ -0,0 +1,180 @@
> >
> +////////////////////////////////////////////////////////////////////////////////
> > +//
> > +//  Licensed to the Apache Software Foundation (ASF) under one or more
> > +//  contributor license agreements.  See the NOTICE file distributed
> with
> > +//  this work for additional information regarding copyright ownership.
> > +//  The ASF licenses this file to You under the Apache License, Version
> 2.0
> > +//  (the "License"); you may not use this file except in compliance with
> > +//  the License.  You may obtain a copy of the License at
> > +//
> > +//      http://www.apache.org/licenses/LICENSE-2.0
> > +//
> > +//  Unless required by applicable law or agreed to in writing, software
> > +//  distributed under the License is distributed on an "AS IS" BASIS,
> > +//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> > +//  See the License for the specific language governing permissions and
> > +//  limitations under the License.
> > +//
> >
> +////////////////////////////////////////////////////////////////////////////////
> > +package org.apache.royale.utils.async
> > +{
> > +  import org.apache.royale.events.EventDispatcher;
> > +  import org.apache.royale.events.Event;
> > +
> > +  /**
> > +   * AsyncTask is a base class for AsyncTasks which let the caller know
> when they are done.
> > +   * AsyncTask is an OOP replacement for Promises and simple callbacks
> which allows for
> > +   * strongly typed async requests with any kind of payload and
> behavior.
> > +   * AsyncTask must be subclassed to be used.
> > +   * The subclass must implement the `run` method to define the
> behavior when the task is "run".
> > +   */
> > +
> > +  [Event(name="complete", type="org.apache.royale.events.Event")]
> > +  [Event(name="failed", type="org.apache.royale.events.Event")]
> > +  [Event(name="done", type="org.apache.royale.events.Event")]
> > +  public abstract class AsyncTask extends EventDispatcher
> > +  {
> > +    public function AsyncTask()
> > +    {
> > +
> > +    }
> > +    public static const INITIALIZED:String = "initialized";
> > +    public static const PENDING:String = "pending";
> > +    public static const COMPLETE:String = "complete";
> > +    public static const CANCELED:String = "canceled";
> > +    public static const FAILED:String = "failed";
> > +    /**
> > +     * Used in compound tasks
> > +     */
> > +    public static const MIXED:String = "mixed";
> > +    protected var _status:String = "initialized";
> > +    /**
> > +     * One of: initialized, pending, complete, failed or mixed (for
> compound tasks)
> > +     *  @langversion 3.0
> > +     *  @playerversion Flash 10.2
> > +     *  @playerversion AIR 2.6
> > +     *  @productversion Royale 0.9.6
> > +     */
> > +    public function get status():String
> > +    {
> > +      return _status;
> > +    }
> > +
> > +    /**
> > +     * completed (and a status of `complete`) means the task completed
> successfully
> > +     *  @langversion 3.0
> > +     *  @playerversion Flash 10.2
> > +     *  @playerversion AIR 2.6
> > +     *  @productversion Royale 0.9.6
> > +     */
> > +    public function get completed():Boolean
> > +    {
> > +     return _status == "complete";
> > +    }
> > +    public function set completed(value:Boolean):void
> > +    {
> > +     _status = "complete";
> > +    }
> > +
> > +    /**
> > +     * failed (and a status of `failed`) means the task resolved to a
> failed state
> > +     *  @langversion 3.0
> > +     *  @playerversion Flash 10.2
> > +     *  @playerversion AIR 2.6
> > +     *  @productversion Royale 0.9.6
> > +     */
> > +    public function get failed():Boolean
> > +    {
> > +     return _status == "failed";
> > +    }
> > +    public function set failed(value:Boolean):void
> > +    {
> > +     _status = "failed";
> > +    }
> > +    /**
> > +     * resolves the task as complete
> > +     *  @langversion 3.0
> > +     *  @playerversion Flash 10.2
> > +     *  @playerversion AIR 2.6
> > +     *  @productversion Royale 0.9.6
> > +     */
> > +    public function complete():void{
> > +      _status = "complete";
> > +      dispatchEvent(new Event("complete"));
> > +      notifyDone();
> > +    }
> > +    /**
> > +     * Resolves the task as failed
> > +     *  @langversion 3.0
> > +     *  @playerversion Flash 10.2
> > +     *  @playerversion AIR 2.6
> > +     *  @productversion Royale 0.9.6
> > +     */
> > +    public function fail():void{
> > +      _status = "failed";
> > +      dispatchEvent(new Event("failed"));
> > +      notifyDone();
> > +    }
> > +    protected function notifyDone():void{
> > +      dispatchEvent(new Event("done"));
> > +      if(!doneCallbacks){
> > +        return;
> > +      }
> > +      for(var i:int=0;i<doneCallbacks.length;i++){
> > +        doneCallbacks[i](this);
> > +      }
> > +    }
> > +    private var doneCallbacks:Array;
> > +
> > +    /**
> > +     * done accepts a callback which is called when the task is
> resolved.
> > +     * The callback is resolved whether the task is successfully
> completed or not.
> > +     * The properties of the task should be examined in the callback to
> determine the results.
> > +     * The `done` event can be listened too as well.
> > +     *  @langversion 3.0
> > +     *  @playerversion Flash 10.2
> > +     *  @playerversion AIR 2.6
> > +     *  @productversion Royale 0.9.6
> > +     */
> > +    public function done(callback:Function):AsyncTask{
> > +      if(!doneCallbacks){
> > +        doneCallbacks = [];
> > +      }
> > +      doneCallbacks.push(callback);
> > +      return this;
> > +    }
> > +    public abstract function run(data:Object=null):void;
> > +
> > +    /**
> > +     * cancel resolves the task as "canceled"
> > +     *  @langversion 3.0
> > +     *  @playerversion Flash 10.2
> > +     *  @playerversion AIR 2.6
> > +     *  @productversion Royale 0.9.6
> > +     */
> > +    public function cancel():void
> > +    {
> > +      _status = "canceled";
> > +      notifyDone();
> > +    }
> > +
> > +    private var _data:Object;
> > +    /**
> > +     * The data of the task
> > +     *  @langversion 3.0
> > +     *  @playerversion Flash 10.2
> > +     *  @playerversion AIR 2.6
> > +     *  @productversion Royale 0.9.6
> > +     */
> > +    public function get data():Object
> > +    {
> > +     return _data;
> > +    }
> > +
> > +    public function set data(value:Object):void
> > +    {
> > +     _data = value;
> > +    }
> > +
> > +  }
> > +}
> > \ No newline at end of file
> > diff --git
> a/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/async/CompoundAsyncTask.as
> b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/async/CompoundAsyncTask.as
> > new file mode 100644
> > index 0000000..3dee5ef
> > --- /dev/null
> > +++
> b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/async/CompoundAsyncTask.as
> > @@ -0,0 +1,135 @@
> >
> +////////////////////////////////////////////////////////////////////////////////
> > +//
> > +//  Licensed to the Apache Software Foundation (ASF) under one or more
> > +//  contributor license agreements.  See the NOTICE file distributed
> with
> > +//  this work for additional information regarding copyright ownership.
> > +//  The ASF licenses this file to You under the Apache License, Version
> 2.0
> > +//  (the "License"); you may not use this file except in compliance with
> > +//  the License.  You may obtain a copy of the License at
> > +//
> > +//      http://www.apache.org/licenses/LICENSE-2.0
> > +//
> > +//  Unless required by applicable law or agreed to in writing, software
> > +//  distributed under the License is distributed on an "AS IS" BASIS,
> > +//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> > +//  See the License for the specific language governing permissions and
> > +//  limitations under the License.
> > +//
> >
> +////////////////////////////////////////////////////////////////////////////////
> > +package org.apache.royale.utils.async
> > +{
> > +  import org.apache.royale.events.Event;
> > +
> > +  /**
> > +   * The CompoundAsyncTask class allows running a number of AsyncTasks
> in parallel and resolves when they are done.
> > +   */
> > +  public class CompoundAsyncTask extends AsyncTask
> > +  {
> > +    public function CompoundAsyncTask(tasks:Array=null)
> > +    {
> > +      super();
> > +      if(!tasks){
> > +        tasks = [];
> > +      }
> > +      this.tasks = tasks;
> > +      completedTasks = [];
> > +      failedTasks = [];
> > +    }
> > +    protected var tasks:Array;
> > +
> > +    private var _failEarly:Boolean;
> > +    /**
> > +     * If <code>failEarly</code> is true, the task will fail as soon as
> the first subtask fails.
> > +     */
> > +    public function get failEarly():Boolean
> > +    {
> > +     return _failEarly;
> > +    }
> > +
> > +    public function set failEarly(value:Boolean):void
> > +    {
> > +     _failEarly = value;
> > +    }
> > +
> > +    public function addTask(task:AsyncTask):void{
> > +      tasks.push(task);
> > +    }
> > +
> > +    protected var pendingTasks:Array;
> > +
> > +    /**
> > +     *  @royalesuppresspublicvarwarning
> > +     */
> > +    public var completedTasks:Array;
> > +    /**
> > +     *  @royalesuppresspublicvarwarning
> > +     */
> > +    public var failedTasks:Array;
> > +
> > +    override public function run(data:Object=null):void
> > +    {
> > +      if(_status == "pending"){// don't allow running twice
> > +        return;
> > +      }
> > +      _status = "pending";
> > +      pendingTasks = [];
> > +      for(var i:int=0;i<tasks.length;i++){
> > +        var task:AsyncTask = tasks[i];
> > +        task.done(handleDone);
> > +        pendingTasks.push(task);
> > +        task.run();
> > +      }
> > +    }
> > +    private function handleDone(task:AsyncTask):void
> > +    {
> > +      if(_status != "pending")
> > +      {
> > +        return;
> > +      }
> > +      var idx:int = pendingTasks.indexOf(task);
> > +      pendingTasks.splice(idx,1);
> > +      switch(task.status){
> > +        case "complete":
> > +          completedTasks.push(task);
> > +          break;
> > +        case "failed":
> > +          failedTasks.push(task);
> > +          if(failEarly)
> > +          {
> > +            while(pendingTasks.length)
> > +            {
> > +              var pending:AsyncTask = pendingTasks.pop();
> > +              pending.cancel();
> > +            }
> > +            fail();
> > +            return;
> > +          }
> > +          break;
> > +        default:// not sure why this would happen
> > +          throw new Error("Unknown task status");
> > +      }
> > +      if(pendingTasks.length == 0)
> > +      {
> > +        setFinalStatus();
> > +      }
> > +    }
> > +    protected function setFinalStatus():void
> > +    {
> > +      if(failedTasks.length == 0)
> > +      {
> > +        complete();
> > +      }
> > +      else if(completedTasks.length == 0)
> > +      {
> > +        fail();
> > +      }
> > +      else
> > +      {// Some passed and some failed -- Does this make sense?
> > +        _status = "mixed";
> > +        dispatchEvent(new Event("failed"));
> > +        dispatchEvent(new Event("complete"));
> > +        notifyDone();
> > +      }
> > +    }
> > +  }
> > +}
> > \ No newline at end of file
> > diff --git
> a/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/async/SequentialAsyncTask.as
> b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/async/SequentialAsyncTask.as
> > new file mode 100644
> > index 0000000..77f2f18
> > --- /dev/null
> > +++
> b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/async/SequentialAsyncTask.as
> > @@ -0,0 +1,77 @@
> >
> +////////////////////////////////////////////////////////////////////////////////
> > +//
> > +//  Licensed to the Apache Software Foundation (ASF) under one or more
> > +//  contributor license agreements.  See the NOTICE file distributed
> with
> > +//  this work for additional information regarding copyright ownership.
> > +//  The ASF licenses this file to You under the Apache License, Version
> 2.0
> > +//  (the "License"); you may not use this file except in compliance with
> > +//  the License.  You may obtain a copy of the License at
> > +//
> > +//      http://www.apache.org/licenses/LICENSE-2.0
> > +//
> > +//  Unless required by applicable law or agreed to in writing, software
> > +//  distributed under the License is distributed on an "AS IS" BASIS,
> > +//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> > +//  See the License for the specific language governing permissions and
> > +//  limitations under the License.
> > +//
> >
> +////////////////////////////////////////////////////////////////////////////////
> > +package org.apache.royale.utils.async
> > +{
> > +  /**
> > +   * The SequentialAsyncTask runs a list of tasks in sequential order.
> > +   * Each sunsequent task is only run once the previous task is done.
> > +   * The previous task is used as the argument for the next task's run
> method.
> > +   * This enables the chaining of results.
> > +   */
> > +  public class SequentialAsyncTask extends CompoundAsyncTask
> > +  {
> > +    /**
> > +     *  @langversion 3.0
> > +     *  @playerversion Flash 10.2
> > +     *  @playerversion AIR 2.6
> > +     *  @productversion Royale 0.9.6
> > +     */
> > +    public function SequentialAsyncTask(tasks:Array=null)
> > +    {
> > +      super(tasks);
> > +    }
> > +    override public function run(data:Object=null):void
> > +    {
> > +      _status = "pending";
> > +      pendingTasks = tasks.slice();
> > +      var task:AsyncTask = pendingTasks.shift();
> > +      task.done(handleDone);
> > +      task.run();
> > +    }
> > +    private function handleDone(task:AsyncTask):void
> > +    {
> > +      if(_status != "pending"){
> > +        return;
> > +      }
> > +      switch(task.status){
> > +        case "complete":
> > +          completedTasks.push(task);
> > +          break;
> > +        case "failed":
> > +          failedTasks.push(task);
> > +          if(failEarly){
> > +            pendingTasks = [];
> > +            fail();
> > +            return;
> > +          }
> > +          break;
> > +        default:// not sure why this would happen
> > +          throw new Error("Unknown task status");
> > +
> > +      }
> > +      if(pendingTasks.length){
> > +        var nextTask:AsyncTask = pendingTasks.shift();
> > +        nextTask.done(handleDone);
> > +        nextTask.run(task);
> > +      } else {
> > +        setFinalStatus();
> > +      }
> > +    }
> > +  }
> > +}
> > \ No newline at end of file
> >
>
>

-- 
Carlos Rovira
http://about.me/carlosrovira

Reply via email to