Jump to content
Search Community

Dries.Cleymans

Members
  • Posts

    5
  • Joined

  • Last visited

Dries.Cleymans's Achievements

0

Reputation

  1. It works, but i would like some advice about performance. Can you estimate the performance impact of this extra piece of code? On every frame we will retrieve the getTimer() value and perform an extra if check. I'm most concerned about the Math.abs() function call this is used in the if check, i don't know if this is heavy piece of code. I'm not worried about the code that is executed when the if check succeeds, this will be almost never be executed. Thanks!
  2. The description in your bullets is very close to what i'm trying to say. Let me change the last bullet a bit: Let's say you've got a delayedCall that's scheduled to be triggered 30 seconds from now... ...but the user then sets their global clock to a time in the past (like 2 weeks ago) before that delayedCall() fires... ...I still want the delayedCall to fire 30 seconds after it was initiated. What is happening now: When a user sets the clock to 2 weeks in the past, the delayedCall is fired 2 weeks and 30 seconds after the initial invocation. A second part of the problem is when the getTimer() method starts to return negative values. This actually happens when the application runs for more than 25 days. The returning value of getTimer() is an int. The int can only contain values between -2,147,483,648 and 2,147,483,647. The getTimer() method suddenly goes from 2,147,483,647 to -2,147,483,648. The getTimer() method aslo switches from positive to negative values when the systems clock is changed for more than 25 days. So when the users changes his clock to one month in the future, the values are suddenly negative. The GSAP framework currently is not handling this correct. I can understand that this does not bother the vast majority of users. It will not happen a lot and when it happens, most users will just restart the app. In our case, we actually have users that want our app to run for weeks. I know it is a bit crazy to run a large flash application for that long.. Based on your advise, I have made some changes to the _updateRoot method of the Animation.as class. With these changes, everything seems to survive a large system clock change. If you see any mistakes that I overlooked, please let me know. I'm not familiar with the internal working of the GSAP framework, but i gave it my best shot to fix this. protected static var _previousTimerTick:int; /** @private This method gets called on every frame and is responsible for rendering/updating the root timelines. If you want to unhook the engine from its ticker, you could do <code>Animation.ticker.removeEventListener("enterFrame", _updateRoot)</code> and then call it yourself whenever you want to update. **/ public static function _updateRoot(event:Event=null):void { _rootFrame++; //START OF ADDED CODE var newTimerTick:int = getTimer(); //check for a timejump //A -> getTimer() flips between a large positive and negative value //B -> there is a gap of 10 seconds between frames if ((newTimerTick < -5000 && _previousTimerTick > 5000) || (_previousTimerTick < -5000 && newTimerTick > 5000) || Math.abs(newTimerTick - _previousTimerTick) > 10000){ //reset root startTime. As a result, _rootTimeline._time will be set to 0 in the next render call _rootTimeline._startTime = newTimerTick / 1000; //RESET ALL RootTimeLine TWEENS var tween:Animation = _rootTimeline._first, next:Animation; while (tween) { next = tween._next; var remainingDelay:Number = tween._startTime - tween._time; //OPTION 1: keep the remaining delay when the time jumps //tween._startTime = remainingDelay; //OPTION 2: all planned tweens and delayed calls will fire immediatly when the time jumps if (remainingDelay > 0){ //setting this to 0 will start all tweens with a delay (and trigger al delayedCalls) tween._startTime = 0; }else{ //running tweens tween._startTime = remainingDelay; } tween = next; } } _previousTimerTick = newTimerTick; //END OF ADDED CODE. _rootTimeline.render(getTimer() / 1000 - _rootTimeline._startTime * _rootTimeline._timeScale, false, false); _rootFramesTimeline.render((_rootFrame - _rootFramesTimeline._startTime) * _rootFramesTimeline._timeScale, false, false); ticker.dispatchEvent(_tickEvent); } As you can see, I believe there are 2 options: With option 1 all delays are taken into account when the time jumps. This looks the most 'correct' way to handle the big time jumps. In our case however, we just want to have all delayed calls triggered when the time jumps for a large chunk. This is what happens with option 2. Note that the if check with < -5000 and > 5000 is needed because we can't perform aritmatic operations to int values that go out of bounds: If the getTimer() goes from 2,147,483,647 to -2,147,483,648 and you substract them from each other, you just get a very small value. Again, thank you for looking into this.
  3. I tried to implement the changes into the Animation.as file, but I failed. I'll post what I have tried so far, maybe this helps to clarify what i have in mind. I tried to update the _updateRoot method, so that it can handle when the getTimer() returns a value that is less than the startTime: public static function _updateRoot(event:Event=null):void { _rootFrame++; //The Math.abs() call is added in the next line _rootTimeline.render(Math.abs(getTimer() / 1000 - _rootTimeline._startTime) * _rootTimeline._timeScale, false, false); _rootFramesTimeline.render((_rootFrame - _rootFramesTimeline._startTime) * _rootFramesTimeline._timeScale, false, false); ticker.dispatchEvent(_tickEvent); } I also tried to reset the startTime when the getTimer() value is below the startTime: public static function _updateRoot(event:Event=null):void { _rootFrame++; //This check has been added if (getTimer() / 1000 < _rootTimeline._startTime){ _rootTimeline._startTime = getTimer() / 1000; } _rootTimeline.render(getTimer() / 1000 - _rootTimeline._startTime * _rootTimeline._timeScale, false, false); _rootFramesTimeline.render((_rootFrame - _rootFramesTimeline._startTime) * _rootFramesTimeline._timeScale, false, false); ticker.dispatchEvent(_tickEvent); } Both ways don't seem to do the job.. maybe the delay should also been taken into account? I also tried to modify the render function of the SimpleTimeline.as file, but failed to get the desired result. I think we have to build some kind of extra check on the time or tween._startTime values to detect if the values are going out of 'normal' boundaries. Thank you for looking into this problem. I understand that the actionscript library is not used by a lot of users lately, but has been very useful to us. All help is greatly appreciated!
  4. Hi, The getTimer() function returns an int, which must contain values between -2,147,483,648 and 2,147,483,647. When you change the system's clock, the getTimer() value changes with it. 2,147,483,647 milliseconds = 24,85 days. When a flash app is running and you change the clock to 25 days in the future, the getTimer() function return a negative value. I suppose that the same happens when the app runs for more than 24,85 days. I noticed that the Tweenmax delayedCall method fires as soon as the getTimer returned value has changed for the requested amount of time. So, it also works for negative values. If the delayedCall is asked to wait for 5 seconds, it will fire when it goes for example from -10000 to -5000. We changed most Timer objects to delayedCalls in our app. We thought that the delayedCalls were more stable and less resource consuming. We have some sort of calendar function with a recursive delayedCall method. This stops to work once the getTimer value gets negative. Maybe the internal working of the delayedCall method can be changed so that it fires as soon as the absolute value for the amount of time has expired. This would make all delayedCalls fire when the getTimer() method goes from a positive value to a negative value. All delayedCalls will also fire when the system's clock is changed to a value in the past. This would be a solution for us. I also noticed that a flash.utils.Timer object keeps on firing when the getTimer() function gets negative. We can build an other work around with this, but the solution above looks a lot better to me.
  5. Hi, We have a flash application that has to run stable for a long time. We have noticed that the delayed calls are not firing when the user decreases the time on his machine. Maybe the delayedCall method internally checks how much time has passed based on the Time() function? The same happens when the application runs for a couple of weeks. Maybe the Time() function is set back to 0 at some point? How can we fix this? thx, Dries
×
×
  • Create New...