LCOV - code coverage report
Current view: top level - xenolith/scene/actions - XLAction.cc (source / functions) Hit Total Coverage
Test: coverage.info Lines: 428 459 93.2 %
Date: 2024-05-12 00:16:13 Functions: 108 109 99.1 %

          Line data    Source code
       1             : /**
       2             :  Copyright (c) 2022 Roman Katuntsev <sbkarr@stappler.org>
       3             :  Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       4             : 
       5             :  Permission is hereby granted, free of charge, to any person obtaining a copy
       6             :  of this software and associated documentation files (the "Software"), to deal
       7             :  in the Software without restriction, including without limitation the rights
       8             :  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       9             :  copies of the Software, and to permit persons to whom the Software is
      10             :  furnished to do so, subject to the following conditions:
      11             : 
      12             :  The above copyright notice and this permission notice shall be included in
      13             :  all copies or substantial portions of the Software.
      14             : 
      15             :  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             :  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             :  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      18             :  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19             :  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      20             :  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      21             :  THE SOFTWARE.
      22             :  **/
      23             : 
      24             : #include "XLAction.h"
      25             : #include "XLNode.h"
      26             : 
      27             : namespace STAPPLER_VERSIONIZED stappler::xenolith {
      28             : 
      29             : SP_COVERAGE_TRIVIAL
      30             : Action::~Action() { }
      31             : 
      32       13021 : Action::Action() { }
      33             : 
      34        2495 : void Action::invalidate() {
      35        2495 :         if (_target) {
      36        2450 :                 stop();
      37             :         }
      38        2495 : }
      39             : 
      40       15624 : void Action::stop() {
      41       15624 :         _target = nullptr;
      42       15624 : }
      43             : 
      44        1084 : bool Action::isDone() const {
      45        1084 :         return _target == nullptr;
      46             : }
      47             : 
      48             : SP_COVERAGE_TRIVIAL
      49             : void Action::step(float dt) {
      50             :         log::warn("Action", "[step]: override me");
      51             : }
      52             : 
      53             : SP_COVERAGE_TRIVIAL
      54             : void Action::update(float time) {
      55             :         log::warn("Action", "[update]: override me");
      56             : }
      57             : 
      58       12959 : void Action::startWithTarget(Node *aTarget) {
      59       12959 :         _target = aTarget;
      60       12959 : }
      61             : 
      62        5102 : void Action::setContainer(Node *container) {
      63        5102 :         _container = container;
      64        5102 : }
      65             : 
      66           0 : void Action::setTarget(Node *target) {
      67           0 :         _target = target;
      68           0 : }
      69             : 
      70             : SP_COVERAGE_TRIVIAL
      71             : ActionInstant::~ActionInstant() { }
      72             : 
      73        1891 : bool ActionInstant::init(bool runOnce) {
      74        1891 :         _duration = 0.0f;
      75        1891 :         _runOnce = runOnce;
      76        1891 :         return true;
      77             : }
      78             : 
      79         517 : void ActionInstant::step(float dt) {
      80         517 :         if (!_performed || !_runOnce) {
      81         517 :             update(1.0f);
      82         517 :             _performed = true;
      83             :         }
      84         517 : }
      85             : 
      86          42 : Show::~Show() { }
      87             : 
      88         137 : void Show::update(float time) {
      89         137 :         _target->setVisible(true);
      90         137 : }
      91             : 
      92          42 : Hide::~Hide() { }
      93             : 
      94         179 : void Hide::update(float time) {
      95         179 :         _target->setVisible(false);
      96         179 : }
      97             : 
      98          84 : ToggleVisibility::~ToggleVisibility() { }
      99             : 
     100         148 : void ToggleVisibility::update(float time) {
     101         148 :         _target->setVisible(!_target->isVisible());
     102         148 : }
     103             : 
     104          42 : RemoveSelf::~RemoveSelf() { }
     105             : 
     106          21 : bool RemoveSelf::init(bool isNeedCleanUp, bool runOnce) {
     107          21 :         if (!ActionInstant::init(runOnce)) {
     108           0 :                 return false;
     109             :         }
     110             : 
     111          21 :         _isNeedCleanUp = isNeedCleanUp;
     112          21 :         return true;
     113             : }
     114             : 
     115          21 : void RemoveSelf::update(float time) {
     116          21 :         _target->removeFromParent(_isNeedCleanUp);
     117          21 : }
     118             : 
     119          42 : Place::~Place() { }
     120             : 
     121          21 : bool Place::init(const Vec2 &pos, bool runOnce) {
     122          21 :         if (!ActionInstant::init(runOnce)) {
     123           0 :                 return false;
     124             :         }
     125             : 
     126          21 :         _position = pos;
     127          21 :         return true;
     128             : }
     129             : 
     130          32 : void Place::update(float time) {
     131          32 :         _target->setPosition(_position);
     132          32 : }
     133             : 
     134        3530 : CallFunc::~CallFunc() { }
     135             : 
     136        1765 : bool CallFunc::init(Function<void()> &&func, bool runOnce) {
     137        1765 :         if (!ActionInstant::init(runOnce)) {
     138           0 :                 return false;
     139             :         }
     140             : 
     141        1765 :         _callback = move(func);
     142        1765 :         return true;
     143             : }
     144             : 
     145        1744 : void CallFunc::update(float time) {
     146        1744 :         _callback();
     147        1744 : }
     148             : 
     149             : SP_COVERAGE_TRIVIAL
     150             : ActionInterval::~ActionInterval() { }
     151             : 
     152       10997 : bool ActionInterval::init(float duration) {
     153       10997 :         _duration = duration;
     154             : 
     155             :         // prevent division by 0
     156             :         // This comparison could be in step:, but it might decrease the performance
     157             :         // by 3% in heavy based action games.
     158       10997 :         _duration = std::max(_duration, FLT_EPSILON);
     159       10997 :         if (_duration == 0) {
     160           0 :                 _duration = FLT_EPSILON;
     161             :         }
     162             : 
     163       10997 :         _elapsed = 0;
     164       10997 :         _firstTick = true;
     165       10997 :         return true;
     166             : }
     167             : 
     168       13641 : void ActionInterval::stop() {
     169       13641 :         _elapsed = _duration;
     170       13641 :         Action::stop();
     171       13641 : }
     172             : 
     173       92329 : bool ActionInterval::isDone() const {
     174       92329 :         return _elapsed >= _duration;
     175             : }
     176             : 
     177       50513 : void ActionInterval::step(float dt) {
     178       50513 :         if (_firstTick) {
     179        4057 :                 _firstTick = false;
     180        4057 :                 _elapsed = 0;
     181             :         } else {
     182       46456 :                 _elapsed += dt;
     183             :         }
     184             : 
     185       50513 :         this->update(math::clamp(_elapsed / _duration, 0.0f, 1.0f));
     186       50513 : }
     187             : 
     188       11068 : void ActionInterval::startWithTarget(Node *target) {
     189       11068 :         Action::startWithTarget(target);
     190       11068 :         _elapsed = 0.0f;
     191       11068 :         _firstTick = true;
     192       11068 : }
     193             : 
     194          21 : void ActionInterval::setDuration(float duration) {
     195          21 :         _duration = std::max(_duration, FLT_EPSILON);
     196          21 : }
     197             : 
     198          42 : Speed::~Speed() { }
     199             : 
     200          21 : Speed::Speed() { }
     201             : 
     202          21 : bool Speed::init(Rc<ActionInterval> &&action, float speed) {
     203          21 :         XLASSERT(action != nullptr, "action must not be NULL");
     204          21 :         setInnerAction(move(action));
     205          21 :         _speed = speed;
     206          21 :         return true;
     207             : }
     208             : 
     209          21 : void Speed::setInnerAction(Rc<ActionInterval> &&action) {
     210          21 :         if (_innerAction != action) {
     211          21 :                 _innerAction = action;
     212             :         }
     213          21 : }
     214             : 
     215          21 : void Speed::startWithTarget(Node *target) {
     216          21 :         Action::startWithTarget(target);
     217          21 :         _innerAction->startWithTarget(target);
     218          21 :         setDuration(_innerAction->getDuration() * _speed);
     219          21 : }
     220             : 
     221          21 : void Speed::stop() {
     222          21 :         _innerAction->stop();
     223          21 :         Action::stop();
     224          21 : }
     225             : 
     226         242 : void Speed::step(float dt) {
     227         242 :         _innerAction->step(dt * _speed);
     228         242 : }
     229             : 
     230         473 : bool Speed::isDone() const {
     231         473 :         return _innerAction->isDone();
     232             : }
     233             : 
     234        4620 : Sequence::~Sequence() { }
     235             : 
     236        2309 : void Sequence::stop(void) {
     237        2309 :         if (_prevTime < 1.0f && _currentIdx < _actions.size()) {
     238        1155 :                 bool finalizeInstants = false;
     239        1155 :                 auto front = _actions.begin() + _currentIdx;
     240        1155 :                 auto end = _actions.end();
     241             : 
     242        1155 :                 front->action->stop();
     243        1155 :                 finalizeInstants = (_prevTime - std::numeric_limits<float>::epsilon()) >= front->maxThreshold;
     244        1155 :                 ++ front;
     245        1155 :                 ++ _currentIdx;
     246             : 
     247        1155 :                 if (finalizeInstants) {
     248           0 :                         while (front != end && front->threshold <= std::numeric_limits<float>::epsilon()) {
     249           0 :                                 front->action->startWithTarget(_target);
     250           0 :                                 front->action->update(1.0);
     251           0 :                                 front->action->stop();
     252             : 
     253           0 :                                 ++ front;
     254           0 :                                 ++ _currentIdx;
     255             :                         }
     256             :                 }
     257             : 
     258             :                 // do not update any non-instant actions, just start-stop
     259        2289 :                 while (front != end) {
     260        1134 :                         front->action->startWithTarget(_target);
     261        1134 :                         front->action->stop();
     262             : 
     263        1134 :                         ++ front;
     264        1134 :                         ++ _currentIdx;
     265             :                 }
     266             : 
     267        1155 :                 _prevTime = 1.0f;
     268             :         }
     269        2309 :         ActionInterval::stop();
     270        2309 : }
     271             : 
     272       24115 : void Sequence::update(float t) {
     273       24115 :         auto front = _actions.begin() + _currentIdx;
     274       24115 :         auto end = _actions.end();
     275             : 
     276       24115 :         auto dt = t - _prevTime;
     277             : 
     278             :         // assume monotonical progress
     279             : 
     280       25884 :         while (front != end && dt != 0) {
     281             :                 // process instants
     282       23036 :                 if (front->threshold <= std::numeric_limits<float>::epsilon()) {
     283             :                         do {
     284         684 :                                 front->action->startWithTarget(_target);
     285         684 :                                 front->action->update(1.0);
     286         684 :                                 front->action->stop();
     287             : 
     288         684 :                                 ++ front;
     289         684 :                                 ++ _currentIdx;
     290         684 :                         } while (front != end && front->threshold == 0.0f);
     291             : 
     292             :                         // start next non-instant
     293         684 :                         if (front == end) {
     294          69 :                                 _prevTime = t;
     295         115 :                                 return;
     296             :                         } else {
     297         615 :                                 front->action->startWithTarget(_target);
     298         615 :                                 front->action->update(0.0);
     299             :                         }
     300             :                 }
     301             : 
     302       22967 :                 auto timeFromActionStart = t - front->minThreshold;
     303       22967 :                 auto actionRelativeTime = timeFromActionStart / front->threshold;
     304             : 
     305       22967 :                 if (actionRelativeTime >= 1.0f - std::numeric_limits<float>::epsilon() || t == 1.0f) {
     306        1815 :                         front->action->update(1.0f);
     307        1815 :                         dt = t - front->maxThreshold;
     308        1815 :                         front->action->stop();
     309             : 
     310        1815 :                         ++ front;
     311        1815 :                         ++ _currentIdx;
     312             : 
     313             :                         // start next non-instant
     314        1815 :                         if (front == end) {
     315          46 :                                 _prevTime = t;
     316          46 :                                 return;
     317        1769 :                         } else if (front->threshold > std::numeric_limits<float>::epsilon()) {
     318          46 :                                 front->action->startWithTarget(_target);
     319          46 :                                 front->action->update(0.0);
     320             :                         }
     321             :                 } else {
     322       21152 :                         front->action->update(actionRelativeTime);
     323       21152 :                         dt = 0.0f;
     324       21152 :                         break;
     325             :                 }
     326             :         }
     327             : 
     328       24000 :         auto tmp = front;
     329       25039 :         while (front != end && front->threshold <= std::numeric_limits<float>::epsilon()) {
     330        1039 :                 front->action->startWithTarget(_target);
     331        1039 :                 front->action->update(1.0);
     332        1039 :                 front->action->stop();
     333             : 
     334        1039 :                 ++ front;
     335        1039 :                 ++ _currentIdx;
     336             :         }
     337             : 
     338       24000 :         if (front != end && tmp != front) {
     339           0 :                 front->action->startWithTarget(_target);
     340           0 :                 front->action->update(0.0);
     341             :         }
     342             : 
     343       24000 :         _prevTime = t;
     344             : }
     345             : 
     346        2309 : void Sequence::startWithTarget(Node *target) {
     347        2309 :         ActionInterval::startWithTarget(target);
     348        2309 :         float threshold = 0.0f;
     349        8178 :         for (auto &it : _actions) {
     350        5869 :                 it.minThreshold = threshold;
     351        5869 :                 it.threshold = it.action->getDuration() / _duration;
     352        5869 :                 threshold += it.threshold;
     353        5869 :                 it.maxThreshold = threshold;
     354             :         }
     355             : 
     356             :         // start first action if it's not instant
     357        2309 :         if (_actions.front().threshold != 0.0f) {
     358        2309 :                 _actions.front().action->startWithTarget(_target);
     359             :         }
     360             : 
     361        2309 :         _prevTime = 0.0f;
     362        2309 :         _currentIdx = 0;
     363        2309 : }
     364             : 
     365        2310 : bool Sequence::reserve(size_t s) {
     366        2310 :         _actions.reserve(s);
     367        2310 :         return true;
     368             : }
     369             : 
     370        1744 : bool Sequence::addAction(Function<void()> &&cb) {
     371        1744 :         auto a = Rc<CallFunc>::create(move(cb));
     372        3488 :         return addAction(a.get());
     373        1744 : }
     374             : 
     375        2879 : bool Sequence::addAction(float time) {
     376        2879 :         auto a = Rc<DelayTime>::create(time);
     377        5758 :         return addAction(a.get());
     378        2879 : }
     379             : 
     380          21 : bool Sequence::addAction(TimeInterval ival) {
     381          21 :         auto a = Rc<DelayTime>::create(ival.toFloatSeconds());
     382          42 :         return addAction(a.get());
     383          21 : }
     384             : 
     385        5871 : bool Sequence::addAction(Action *a) {
     386        5871 :         _duration += a->getDuration();
     387        5871 :         _actions.emplace_back(ActionData{a});
     388        5871 :         return true;
     389             : }
     390             : 
     391          58 : Spawn::~Spawn() { }
     392             : 
     393          39 : void Spawn::stop(void) {
     394          39 :         if (_prevTime < 1.0f) {
     395         150 :                 for (auto &it : _actions) {
     396         123 :                         if (it.threshold >= _prevTime) {
     397          96 :                                 it.action->stop();
     398             :                         }
     399             :                 }
     400          27 :                 _prevTime = 1.0f;
     401             :         }
     402          39 :         ActionInterval::stop();
     403          39 : }
     404             : 
     405         366 : void Spawn::update(float t) {
     406        2032 :         for (auto &it : _actions) {
     407        1666 :                 if (t >= it.threshold && _prevTime < it.threshold) {
     408          33 :                         it.action->update(1.0f);
     409          33 :                         it.action->stop();
     410        1633 :                 } else if (t < it.threshold) {
     411        1320 :                         it.action->update( t * it.threshold );
     412             :                 }
     413             :         }
     414             : 
     415         366 :         _prevTime = t;
     416         366 : }
     417             : 
     418          29 : void Spawn::startWithTarget(Node *target) {
     419          29 :         ActionInterval::startWithTarget(target);
     420         158 :         for (auto &it : _actions) {
     421         129 :                 it.threshold = it.action->getDuration() / _duration - std::numeric_limits<float>::epsilon();
     422         129 :                 it.action->startWithTarget(target);
     423             :         }
     424             : 
     425          29 :         _prevTime = - std::numeric_limits<float>::epsilon() * 2;
     426          29 : }
     427             : 
     428          29 : bool Spawn::reserve(size_t s) {
     429          29 :         _actions.reserve(s);
     430          29 :         return true;
     431             : }
     432             : 
     433          21 : bool Spawn::addAction(Function<void()> &&cb) {
     434          21 :         auto a = Rc<CallFunc>::create(move(cb));
     435          42 :         return addAction(a.get());
     436          21 : }
     437             : 
     438          21 : bool Spawn::addAction(float time) {
     439          21 :         auto a = Rc<DelayTime>::create(time);
     440          42 :         return addAction(a.get());
     441          21 : }
     442             : 
     443         129 : bool Spawn::addAction(Action *a) {
     444         129 :         _duration = std::max(_duration, a->getDuration());
     445         129 :         _actions.emplace_back(ActionData{a});
     446         129 :         return true;
     447             : }
     448             : 
     449             : SP_COVERAGE_TRIVIAL
     450             : Repeat::~Repeat() {
     451             :         _innerAction = nullptr;
     452             : }
     453             : 
     454          21 : bool Repeat::init(Rc<ActionInterval> &&action, uint32_t times) {
     455          21 :     float d = action->getDuration() * times;
     456             : 
     457          21 :         if (ActionInterval::init(d)) {
     458          21 :                 _times = times;
     459          21 :                 setInnerAction(move(action));
     460          21 :                 _actionInstant = dynamic_cast<ActionInstant *>(action.get()) ? true : false;
     461          21 :                 if (_actionInstant) {
     462           0 :                         _times -= 1;
     463             :                 }
     464          21 :                 _total = 0;
     465          21 :                 return true;
     466             :         }
     467             : 
     468           0 :         return false;
     469             : }
     470             : 
     471          21 : void Repeat::setInnerAction(Rc<ActionInterval> &&action) {
     472          21 :         if (_innerAction != action) {
     473          21 :                 _innerAction = move(action);
     474             :         }
     475          21 : }
     476             : 
     477        1333 : void Repeat::stop() {
     478        1333 :         _innerAction->stop();
     479        1333 :         ActionInterval::stop();
     480        1333 : }
     481             : 
     482         242 : void Repeat::update(float dt) {
     483         242 :         if (dt >= _nextDt) {
     484          42 :                 while (dt > _nextDt && _total < _times) {
     485          21 :                         _innerAction->update(1.0f);
     486          21 :                         ++ _total;
     487             : 
     488          21 :                         _innerAction->stop();
     489          21 :                         _innerAction->startWithTarget(_target);
     490          21 :                         _nextDt = _innerAction->getDuration() / _duration * (_total + 1);
     491             :                 }
     492             : 
     493          21 :                 if (dt >= 1.0f && _total < _times) {
     494           0 :                         ++ _total;
     495             :                 }
     496             : 
     497             :                 // don't set an instant action back or update it, it has no use because it has no duration
     498          21 :                 if (!_actionInstant) {
     499          21 :                         if (_total == _times) {
     500           0 :                                 _innerAction->update(1);
     501           0 :                                 _innerAction->stop();
     502             :                         } else {
     503          21 :                                 _innerAction->update(dt - (_nextDt - _innerAction->getDuration() / _duration));
     504             :                         }
     505             :                 }
     506             :         } else {
     507         221 :                 _innerAction->update(fmodf(dt * _times, 1.0f));
     508             :         }
     509         242 : }
     510             : 
     511          21 : void Repeat::startWithTarget(Node *target) {
     512          21 :         _total = 0;
     513          21 :         _nextDt = _innerAction->getDuration() / _duration;
     514          21 :         ActionInterval::startWithTarget(target);
     515          21 :         _innerAction->startWithTarget(target);
     516          21 : }
     517             : 
     518        1796 : bool Repeat::isDone() const {
     519        1796 :         return _total == _times;
     520             : }
     521             : 
     522             : SP_COVERAGE_TRIVIAL
     523             : RepeatForever::~RepeatForever() {
     524             :         _innerAction = nullptr;
     525             : }
     526             : 
     527         112 : bool RepeatForever::init(ActionInterval *action) {
     528         112 :         _innerAction = action;
     529         112 :         return true;
     530             : }
     531             : 
     532         112 : void RepeatForever::startWithTarget(Node *target) {
     533         112 :         ActionInterval::startWithTarget(target);
     534         112 :         _innerAction->startWithTarget(target);
     535         112 : }
     536             : 
     537        4062 : void RepeatForever::step(float dt) {
     538        4062 :         _innerAction->step(dt);
     539        4062 :         if (_innerAction->isDone()) {
     540          52 :                 float diff = _innerAction->getElapsed() - _innerAction->getDuration();
     541          52 :                 if (diff > _innerAction->getDuration()) {
     542           0 :                         diff = fmodf(diff, _innerAction->getDuration());
     543             :                 }
     544          52 :                 _innerAction->startWithTarget(_target);
     545          52 :                 _innerAction->step(0.0f);
     546          52 :                 _innerAction->step(diff);
     547             :         }
     548        4062 : }
     549             : 
     550        8102 : bool RepeatForever::isDone() const {
     551        8102 :         return false;
     552             : }
     553             : 
     554        6178 : DelayTime::~DelayTime() { }
     555             : 
     556       25081 : void DelayTime::update(float time) { }
     557             : 
     558          42 : TintTo::~TintTo() { }
     559             : 
     560          21 : bool TintTo::init(float duration, const Color4F &to, ColorMask mask) {
     561          21 :         if (!ActionInterval::init(duration)) {
     562           0 :                 return false;
     563             :         }
     564             : 
     565          21 :         _to = to;
     566          21 :         _mask = mask;
     567             : 
     568          21 :         return true;
     569             : }
     570             : 
     571          21 : void TintTo::startWithTarget(Node *target) {
     572          21 :         ActionInterval::startWithTarget(target);
     573          21 :         if (target) {
     574          21 :                 _from = target->getColor();
     575          21 :                 _to.setUnmasked(_from, _mask);
     576             :         }
     577          21 : }
     578             : 
     579         284 : void TintTo::update(float time) {
     580         284 :         _target->setColor(progress(_from, _to, time), true);
     581         284 : }
     582             : 
     583         855 : bool ActionProgress::init(float duration, UpdateCallback &&update, StartCallback &&start, StopCallback &&stop) {
     584         855 :         return init(duration, 0.0f, 1.0f, move(update), move(start), move(stop));
     585             : }
     586             : 
     587         798 : bool ActionProgress::init(float duration, float targetProgress, UpdateCallback &&update, StartCallback &&start, StopCallback &&stop) {
     588         798 :         return init(duration, 0.0f, targetProgress, move(update), move(start), move(stop));
     589             : }
     590             : 
     591        1674 : bool ActionProgress::init(float duration, float sourceProgress, float targetProgress,
     592             :                 UpdateCallback &&update, StartCallback &&start, StopCallback &&stop) {
     593        1674 :         if (!ActionInterval::init(duration)) {
     594           0 :                 return false;
     595             :         }
     596             : 
     597        1674 :         _sourceProgress = sourceProgress;
     598        1674 :         _targetProgress = targetProgress;
     599        1674 :         _onUpdate = move(update);
     600        1674 :         _onStart = move(start);
     601        1674 :         _onStop = move(stop);
     602             : 
     603        1674 :         return true;
     604             : }
     605             : 
     606        1678 : void ActionProgress::startWithTarget(Node *t) {
     607        1678 :         ActionInterval::startWithTarget(t);
     608        1678 :         _stopped = false;
     609        1678 :         if (_onStart) {
     610         721 :                 _onStart();
     611             :         }
     612        1678 : }
     613             : 
     614       12621 : void ActionProgress::update(float time) {
     615       12621 :         if (_onUpdate) {
     616       12621 :                 _onUpdate(_sourceProgress + (_targetProgress - _sourceProgress) * time);
     617             :         }
     618       12621 : }
     619             : 
     620        1581 : void ActionProgress::stop() {
     621        1581 :         if (!_stopped && _onStop) {
     622         700 :                 _onStop();
     623             :         }
     624        1581 :         _stopped = true;
     625        1581 :         ActionInterval::stop();
     626        1581 : }
     627             : 
     628         806 : bool MoveTo::init(float duration, const Vec2 &position) {
     629         806 :         if (!ActionInterval::init(duration)) {
     630           0 :                 return false;
     631             :         }
     632             : 
     633         806 :         _endPosition = Vec3(position.x, position.y, nan());
     634         806 :         return true;
     635             : }
     636             : 
     637          21 : bool MoveTo::init(float duration, const Vec3 &position) {
     638          21 :         if (!ActionInterval::init(duration)) {
     639           0 :                 return false;
     640             :         }
     641             : 
     642          21 :         _endPosition = position;
     643          21 :         return true;
     644             : }
     645             : 
     646         848 : void MoveTo::startWithTarget(Node *target) {
     647         848 :         ActionInterval::startWithTarget(target);
     648         848 :         _startPosition = target->getPosition();
     649         848 :         if (isnan(_endPosition.z)) {
     650         806 :                 _endPosition.z = _startPosition.z;
     651             :         }
     652         848 : }
     653             : 
     654        8496 : void MoveTo::update(float time) {
     655        8496 :         _target->setPosition(progress(_startPosition, _endPosition, time));
     656        8496 : }
     657             : 
     658          21 : bool ScaleTo::init(float duration, float scale) {
     659          21 :         if (!ActionInterval::init(duration)) {
     660           0 :                 return false;
     661             :         }
     662             : 
     663          21 :         _endScale = Vec3(scale, scale, scale);
     664          21 :         return true;
     665             : }
     666             : 
     667          21 : bool ScaleTo::init(float duration, const Vec3 &scale) {
     668          21 :         if (!ActionInterval::init(duration)) {
     669           0 :                 return false;
     670             :         }
     671             : 
     672          21 :         _endScale = scale;
     673          21 :         return true;
     674             : }
     675             : 
     676          63 : void ScaleTo::startWithTarget(Node *target) {
     677          63 :         ActionInterval::startWithTarget(target);
     678          63 :         _startScale = target->getScale();
     679          63 : }
     680             : 
     681         547 : void ScaleTo::update(float time) {
     682         547 :         _target->setScale(progress(_startScale, _endScale, time));
     683         547 : }
     684             : 
     685           8 : bool ResizeTo::init(float duration, const Size2 &size) {
     686           8 :         if (!ActionInterval::init(duration)) {
     687           0 :                 return false;
     688             :         }
     689             : 
     690           8 :         _endSize = size;
     691           8 :         return true;
     692             : }
     693             : 
     694           8 : void ResizeTo::startWithTarget(Node *target) {
     695           8 :         ActionInterval::startWithTarget(target);
     696           8 :         _startSize = target->getContentSize();
     697           8 : }
     698             : 
     699          82 : void ResizeTo::update(float time) {
     700          82 :         _target->setContentSize(progress(_startSize, _endSize, time));
     701          82 : }
     702             : 
     703        1277 : bool FadeTo::init(float duration, float target) {
     704        1277 :         if (!ActionInterval::init(duration)) {
     705           0 :                 return false;
     706             :         }
     707             : 
     708        1277 :         _endOpacity = target;
     709        1277 :         return true;
     710             : }
     711             : 
     712        1276 : void FadeTo::startWithTarget(Node *target) {
     713        1276 :         ActionInterval::startWithTarget(target);
     714        1276 :         _startOpacity = target->getOpacity();
     715        1276 : }
     716             : 
     717        1312 : void FadeTo::update(float time) {
     718        1312 :         _target->setOpacity(progress(_startOpacity, _endOpacity, time));
     719        1312 : }
     720             : 
     721          42 : bool RenderContinuously::init() {
     722          42 :         _innerAction = Rc<RepeatForever>::create(Rc<DelayTime>::create(1.0f));
     723             : 
     724          42 :         if (_innerAction) {
     725          42 :                 return ActionInterval::init(_innerAction->getDuration());
     726             :         }
     727           0 :         return false;
     728             : }
     729             : 
     730          21 : bool RenderContinuously::init(float duration) {
     731          21 :         _innerAction = Rc<DelayTime>::create(1.0f);
     732             : 
     733          21 :         if (_innerAction) {
     734          21 :                 return ActionInterval::init(_innerAction->getDuration());
     735             :         }
     736           0 :         return false;
     737             : }
     738             : 
     739        1756 : void RenderContinuously::step(float dt) {
     740        1756 :         ActionInterval::step(dt);
     741        1756 :         _innerAction->step(dt);
     742        1756 : }
     743             : 
     744          63 : void RenderContinuously::startWithTarget(Node *target) {
     745          63 :         ActionInterval::startWithTarget(target);
     746          63 :         _innerAction->startWithTarget(target);
     747          63 : }
     748             : 
     749        2040 : void RenderContinuously::update(float time) {
     750             :         // do nothing
     751        2040 : }
     752             : 
     753        3521 : bool RenderContinuously::isDone(void) const {
     754        3521 :         return _innerAction->isDone();
     755             : }
     756             : 
     757          51 : void RenderContinuously::stop() {
     758          51 :         _innerAction->stop();
     759          51 :         ActionInterval::stop();
     760          51 : }
     761             : 
     762             : 
     763             : }

Generated by: LCOV version 1.14