I would assume that goog.bind would be optimized by gcc if it can be
(perhaps it is inlined if it uses es5 function.protoype.bind internally- I
did not look inside it)

The function naming/caching in Language.closure is important, including
private naming conventions when they are needed for closures.

Did you test this with your chsnges:

var f1:Function = myInst.method;
var f2:Function = myInst.method;

trace(f1 == f2)




On Thu, 6 Jan 2022, 1:37 am Harbs, <harbs.li...@gmail.com> wrote:

> My problem with apply was user error because I was using spread arguments
> which was actually creating an arrays of arrays.
>
> But my question about Language.closure stands.
>
> In my tests it looks like that works.
>
> > On Jan 5, 2022, at 2:21 PM, Harbs <harbs.li...@gmail.com> wrote:
> >
> > So this is weird.
> >
> > Function.prototype.apply is supposed to be able to take an array of
> arguments and apply them to another function. (different from call where
> you have to specify the arguments separately.)
> >
> > It looks to me like a function which was bound to an object (such as one
> wrapped by Language.closure) has the array passed into the first argument
> as an array instead of being passed in as a list of arguments.
> >
> > I have not seen this documented anywhere, but that’s what I’m seeing.
> >
> > Hmm. Actually, not sure about this. goog.bind is doing some weird stuff.
> Maybe that’s causing what I’m seeing? Why are we using goog.bind and not
> just the following in Language.closure?
> >
> > static public function closure(fn:Function, object:Object):Function {
> >  return function() {
> >    return fn.apply(object, arguments);
> >  };
> > }
> >
> > My understanding is that code will correctly bind the function call to
> this.
> >
> > It’s simpler, doesn’t require goog.bind and doesn’t require passing in
> function names.
> >
> > Am I missing something?
> >
> > Harbs
> >
> >> On Jan 5, 2022, at 9:37 AM, Harbs <harbs.li...@gmail.com> wrote:
> >>
> >> This function is a cool one. It lets you animate *anything*. You just
> specify a target fps and run an arbitrary function and it’ll automatically
> be spaced to execute at the target speed:
> >>
> >> The following will increment a value once every 50ms (1000/20fps) and
> run exactly 30 times.
> >>
> >> var value:Number = 0;
> >> function increment(val:Number):void{
> >>      value+=val;
> >> }
> >> var animated:Function = animateFunction(increment,20);
> >> var savedValue:Number;
> >> for(i=0;i<30;i++){
> >>      animated(1);
> >> }
> >>
> >> Have fun! B-)
> >> Harbs
> >>
> >>> On Jan 5, 2022, at 9: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 dd1c6e4  Added animateFunction
> >>> dd1c6e4 is described below
> >>>
> >>> commit dd1c6e4cd7b082207a39efbf71de31adbb6de0d9
> >>> Author: Harbs <ha...@in-tools.com>
> >>> AuthorDate: Wed Jan 5 09:31:10 2022 +0200
> >>>
> >>>  Added animateFunction
> >>> ---
> >>> .../projects/Core/src/main/royale/CoreClasses.as   |   1 +
> >>> .../royale/utils/functional/animateFunction.as     | 130
> +++++++++++++++++++++
> >>> .../src/test/royale/flexUnitTests/CoreTester.as    |   2 +-
> >>> .../test/royale/flexUnitTests/FunctionalTests.as   |  34 ++++++
> >>> 4 files changed, 166 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/frameworks/projects/Core/src/main/royale/CoreClasses.as
> b/frameworks/projects/Core/src/main/royale/CoreClasses.as
> >>> index 50c3c71..48189b5 100644
> >>> --- a/frameworks/projects/Core/src/main/royale/CoreClasses.as
> >>> +++ b/frameworks/projects/Core/src/main/royale/CoreClasses.as
> >>> @@ -382,6 +382,7 @@ internal class CoreClasses
> >>>     import org.apache.royale.utils.functional.debounceLong;
> debounceLong;
> >>>     import org.apache.royale.utils.functional.debounceShort;
> debounceShort;
> >>>     import org.apache.royale.utils.functional.throttle; throttle;
> >>> +   import org.apache.royale.utils.functional.animateFunction;
> animateFunction;
> >>>
> >>>     import org.apache.royale.core.TextLineMetrics; TextLineMetrics;
> >>>     import org.apache.royale.utils.ClassSelectorList;
> ClassSelectorList;
> >>> diff --git
> a/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/functional/animateFunction.as
> b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/functional/animateFunction.as
> >>> new file mode 100644
> >>> index 0000000..32b9fbf
> >>> --- /dev/null
> >>> +++
> b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/functional/animateFunction.as
> >>> @@ -0,0 +1,130 @@
> >>>
> +////////////////////////////////////////////////////////////////////////////////
> >>> +//
> >>> +//  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.functional
> >>> +{
> >>> +   COMPILE::SWF{
> >>> +           import flash.utils.setTimeout;
> >>> +           import flash.utils.clearTimeout;
> >>> +   }
> >>> +   /**
> >>> +    * Returns a debounced function to run after a delay.
> >>> +    * The first invocation of the function will be run after its
> delay.
> >>> +    * Any invocations between the first invocation and the delay will
> be ignored.
> >>> +    *
> >>> +   * @royalesuppressexport
> >>> +    * @langversion 3.0
> >>> +    * @productversion Royale 0.9.9
> >>> +    *
> >>> +    */
> >>> +   public function animateFunction(method:Function,
> fps:Number):Function
> >>> +   {
> >>> +           COMPILE::SWF
> >>> +           {
> >>> +                   var limit:Number = 1000/fps;
> >>> +                   var timeStamp:Number = 0;
> >>> +                   var timeoutRef:*;
> >>> +                   var invocations:Array = [];
> >>> +                   return function(...args):void
> >>> +                   {
> >>> +                           if(timeoutRef){
> >>> +                                   clearTimeout(timeoutRef);
> >>> +                                   timeoutRef = null;
> >>> +                           }
> >>> +                           invocations.push(args);
> >>> +                           var currentTime:Number = new
> Date().getTime();
> >>> +                           var timeDiff:Number = currentTime -
> timeStamp;
> >>> +                           if(timeDiff >= limit)
> >>> +                           {
> >>> +                                   if(timeStamp == 0)
> >>> +                                           timeStamp = currentTime;
> >>> +                                   else
> >>> +                                           timeStamp += limit;
> >>> +
>  method.apply(null,invocations.shift());
> >>> +                           }
> >>> +                           if(invocations.length && timeoutRef ==
> null)
> >>> +                           {
> >>> +                                   // currentTime = new
> Date().getTime();
> >>> +                                   timeDiff = currentTime - timeStamp
> + limit;
> >>> +                                   var nextInterval:Number =
> Math.max(timeDiff,0);
> >>> +                                   timeoutRef = setTimeout(callback,
> nextInterval);
> >>> +                           }
> >>> +
> >>> +                           function callback():void
> >>> +                           {
> >>> +                                   timeoutRef = null;
> >>> +
> >>> +                                   if(!invocations.length)
> >>> +                                           return;
> >>> +
> >>> +                                   var currentArgs:Array =
> invocations.shift();
> >>> +                                   method.apply(null,currentArgs);
> >>> +                                   timeStamp += limit;
> >>> +                                   var timeDiff:Number = new
> Date().getTime() - timeStamp + limit;
> >>> +                                   while(timeDiff < 0)
> >>> +                                   {
> >>> +                                           // catch up on the missing
> frames
> >>> +
>  method.apply(null,invocations.shift());
> >>> +                                           if(invocations.length == 0)
> >>> +                                           {
> >>> +                                                   return;
> >>> +                                           }
> >>> +                                           timeDiff+=limit;
> >>> +                                   }
> >>> +                                   if(invocations.length)
> >>> +                                   {
> >>> +                                           timeoutRef =
> setTimeout(callback, timeDiff);
> >>> +                                   }
> >>> +                           }
> >>> +                   }
> >>> +
> >>> +           }
> >>> +
> >>> +           COMPILE::JS
> >>> +           {
> >>> +                   var limit:Number = 1000/fps;
> >>> +                   var lastTimeStamp:Number = 0;
> >>> +                   var timeoutRef:*;
> >>> +                   var invocations:Array = [];
> >>> +                   return function(...args):void
> >>> +                   {
> >>> +                           invocations.push(args);
> >>> +                           requestAnimationFrame(callback);
> >>> +                           function callback(timeStamp:Number):void
> >>> +                           {
> >>> +                                   if(invocations.length == 0)
> >>> +                                           return;
> >>> +
> >>> +                                   // we can't rely on getting time
> stamps ourselves,
> >>> +                                   // so hopefully this is not slower
> than our target rate...
> >>> +                                   if ( (timeStamp - lastTimeStamp)
> >= limit)
> >>> +                                   {
> >>> +                                           if(lastTimeStamp == 0)
> >>> +                                                   lastTimeStamp =
> timeStamp;
> >>> +                                           else
> >>> +                                                   lastTimeStamp +=
> limit; // make sure we stick to the desired rate
> >>> +
> >>> +
>  method.apply(null,invocations.shift());
> >>> +                                   }
> >>> +                                   if(invocations.length)
> >>> +
>  requestAnimationFrame(callback);
> >>> +                           }
> >>> +                   }
> >>> +           }
> >>> +   }
> >>> +}
> >>> \ No newline at end of file
> >>> diff --git
> a/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as
> b/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as
> >>> index 7b15375..eeb4e76 100644
> >>> ---
> a/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as
> >>> +++
> b/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as
> >>> @@ -45,7 +45,7 @@ package flexUnitTests
> >>>       public var sanitizerTest:SanitizeTest;
> >>>       public var eventsTest:EventsTest;
> >>>       public var objectUtilTests:ObjectUtilsTest;
> >>> -        public var functionelTests:FunctionalTests;
> >>> +        public var functionalTests:FunctionalTests;
> >>>
> >>>   }
> >>> }
> >>> diff --git
> a/frameworks/projects/Core/src/test/royale/flexUnitTests/FunctionalTests.as
> b/frameworks/projects/Core/src/test/royale/flexUnitTests/FunctionalTests.as
> >>> index 022c4da..75f320c 100644
> >>> ---
> a/frameworks/projects/Core/src/test/royale/flexUnitTests/FunctionalTests.as
> >>> +++
> b/frameworks/projects/Core/src/test/royale/flexUnitTests/FunctionalTests.as
> >>> @@ -25,6 +25,8 @@ package flexUnitTests
> >>>   import org.apache.royale.test.asserts.*;
> >>>     import org.apache.royale.test.async.*;
> >>>   import org.apache.royale.utils.functional.*;
> >>> +    import org.apache.royale.utils.functional.animateFunction;
> >>> +    import org.apache.royale.test.asserts.assertTrue;
> >>>
> >>>   public class FunctionalTests
> >>>   {
> >>> @@ -192,6 +194,38 @@ package flexUnitTests
> >>>               assertEquals(value,7,"value should be 7");
> >>>           }, 300);
> >>>       }
> >>> +        [Test(async,timeout="300")]
> >>> +        public function testAnimate():void
> >>> +        {
> >>> +            var foo:Foo = new Foo();
> >>> +            var animateThis:Function =
> animateFunction(foo.increment,20);
> >>> +            for(var i:int=0;i<30;i++){
> >>> +                animateThis(1);
> >>> +            }
> >>> +            var savedThisValue:Number;
> >>> +            setTimeout(function():void{
> >>> +                savedThisValue = foo.value;
> >>> +            },50);
> >>> +
> >>> +            var value:Number = 0;
> >>> +            function increment(val:Number):void{
> >>> +                value+=val;
> >>> +            }
> >>> +            var animated:Function = animateFunction(increment,20);
> >>> +            var savedValue:Number;
> >>> +            for(i=0;i<30;i++){
> >>> +                animated(1);
> >>> +            }
> >>> +
> >>> +            setTimeout(function():void{
> >>> +                savedValue = value;
> >>> +            },50);
> >>> +            Async.delayCall(this, function():void
> >>> +            {
> >>> +                assertTrue(savedThisValue<3,"foo value should be 2");
> >>> +                assertTrue(savedValue<3,"value should be 2");
> >>> +            }, 300);
> >>> +        }
> >>>
> >>>
> >>>   }
> >>
> >
>
>

Reply via email to