//Optimize this? // Returns true if an animation was found and deleted void CUnitScript::RemoveAnim(AnimType type, int piece, int axis) { struct AnimInfo *remove = NULL; for (std::list<struct AnimInfo *>::iterator i = anims.begin(); i != anims.end(); ++i) { struct AnimInfo *ai = *i; if ((ai->type == type) && (ai->piece == piece) && (ai->axis == axis)) { remove = ai; break; } } if (remove) { // We need to unblock threads waiting on this animation, otherwise they will be lost in the void UnblockAll(remove); //! NOTE: UnblockAll might result in new anims being added anims.remove(remove); delete remove; // If this was the last animation, remove from currently animating list if (anims.empty()) { GUnitScriptEngine.RemoveInstance(this); } } }
/** * @brief Called by the engine when we are registered as animating. If we return false there are no active animations left. * @param deltaTime int delta time to update * @return true if there are still active animations */ bool CUnitScript::Tick(int deltaTime) { typedef std::list<AnimInfo*>::iterator AnimInfoIt; // list of _iterators_ to finished animations, // so we can get rid of them in constant time std::list<AnimInfoIt> doneAnims; for (int animType = ATurn; animType <= AMove; animType++) { TickAnims(deltaTime, AnimType(animType), doneAnims); } //! Tell listeners to unblock, and remove finished animations from the unit/script. //! NOTE: //! removing a finished animation _must_ happen before notifying its listeners, //! otherwise the callback function (AnimFinished()) can call AddAnimListener() //! and append it to the listeners-list again (causing an endless loop)! //! NOTE: UnblockAll might result in new anims being added for (std::list<AnimInfoIt>::const_iterator it = doneAnims.begin(); it != doneAnims.end(); ++it) { AnimInfoIt animInfoIt = *it; AnimInfo* animInfo = *animInfoIt; anims[animInfo->type].erase(animInfoIt); UnblockAll(animInfo); delete animInfo; } return (HaveAnimations()); }
/** * @brief Called by the engine when we are registered as animating. If we return -1 it means that * there is no longer anything animating * @param deltaTime int delta time to update * @return 0 if there are still animations going, -1 else */ int CUnitScript::Tick(int deltaTime) { std::vector<struct AnimInfo *> remove; for (std::list<struct AnimInfo *>::iterator it = anims.begin(); it != anims.end(); ) { struct AnimInfo *ai = *it; bool done = false; switch (ai->type) { case AMove: { float3 pos = pieces[ai->piece]->GetPosition(); done = MoveToward(pos[ai->axis], ai->dest, ai->speed / (1000 / deltaTime)); pieces[ai->piece]->SetPosition(pos); } break; case ATurn: { float3 rot = pieces[ai->piece]->GetRotation(); done = TurnToward(rot[ai->axis], ai->dest, ai->speed / (1000 / deltaTime)); pieces[ai->piece]->SetRotation(rot); } break; case ASpin: { float3 rot = pieces[ai->piece]->GetRotation(); done = DoSpin(rot[ai->axis], ai->dest, ai->speed, ai->accel, 1000 / deltaTime); pieces[ai->piece]->SetRotation(rot); } break; } // Queue for removal (UnblockAll may add new anims) if (done) { remove.push_back(ai); } ++it; } //Tell listeners to unblock? for (std::vector<struct AnimInfo *>::iterator it = remove.begin(); it != remove.end(); ++it) { UnblockAll(*it); //! NOTE: UnblockAll might result in new anims being added } for (std::vector<struct AnimInfo *>::iterator it = remove.begin(); it != remove.end(); ++it) { anims.remove(*it); delete *it; } return anims.empty() ? -1 : 0; }
void CUnitScript::RemoveAnim(AnimType type, const std::list<AnimInfo*>::iterator& animInfoIt) { if (animInfoIt != anims[type].end()) { AnimInfo* ai = *animInfoIt; anims[type].erase(animInfoIt); // If this was the last animation, remove from currently animating list // FIXME: this could be done in a cleaner way if (!HaveAnimations()) { GUnitScriptEngine.RemoveInstance(this); } //! We need to unblock threads waiting on this animation, otherwise they will be lost in the void //! NOTE: UnblockAll might result in new anims being added UnblockAll(ai); delete ai; } }
// Returns true if an animation was found and deleted void CCobInstance::RemoveAnim(AnimType type, int piece, int axis) { for (list<struct AnimInfo *>::iterator i = anims.begin(); i != anims.end(); ++i) { if (((*i)->type == type) && ((*i)->piece == piece) && ((*i)->axis == axis)) { // We need to unblock threads waiting on this animation, otherwise they will be lost in the void UnblockAll(*i); delete *i; anims.erase(i); // If this was the last animation, remove from currently animating list if (anims.size() == 0) { GCobEngine.RemoveInstance(this); } return; } } }
/** * @brief Called by the engine when we are registered as animating. If we return -1 it means that * there is no longer anything animating * @param deltaTime int delta time to update * @return 0 if there are still animations going, -1 else */ int CUnitScript::Tick(int deltaTime) { std::vector<struct AnimInfo *> remove; for (std::list<struct AnimInfo *>::iterator it = anims.begin(); it != anims.end(); ) { struct AnimInfo *ai = *it; bool done = false; switch (ai->type) { case AMove: done = MoveToward(pieces[ai->piece]->pos[ai->axis], ai->dest, ai->speed / (1000 / deltaTime)); break; case ATurn: done = TurnToward(pieces[ai->piece]->rot[ai->axis], ai->dest, ai->speed / (1000 / deltaTime)); break; case ASpin: done = DoSpin(pieces[ai->piece]->rot[ai->axis], ai->dest, ai->speed, ai->accel, 1000 / deltaTime); break; } // Queue for removal (UnblockAll may add new anims) if (done) { remove.push_back(ai); it = anims.erase(it); } else { ++it; } } //Tell listeners to unblock? for (std::vector<struct AnimInfo *>::iterator it = remove.begin(); it != remove.end(); ++it) { UnblockAll(*it); delete *it; } if (anims.empty()) return -1; else return 0; }
//Optimize this? // Returns true if an animation was found and deleted void CUnitScript::RemoveAnim(AnimType type, int piece, int axis) { for (std::list<struct AnimInfo *>::iterator i = anims.begin(); i != anims.end(); ++i) { struct AnimInfo *ai = *i; if ((ai->type == type) && (ai->piece == piece) && (ai->axis == axis)) { anims.erase(i); // We need to unblock threads waiting on this animation, otherwise they will be lost in the void UnblockAll(ai); delete ai; // If this was the last animation, remove from currently animating list if (anims.empty()) { GUnitScriptEngine.RemoveInstance(this); } return; } } }
//Called by the engine when we are registered as animating. If we return -1 it means that //there is no longer anything animating int CCobInstance::Tick(int deltaTime) { int done; list<struct AnimInfo *>::iterator it = anims.begin(); list<struct AnimInfo *>::iterator cur; while (it != anims.end()) { //Advance it, so we can erase cur safely cur = it++; done = false; pieces[(*cur)->piece].updated = true; switch ((*cur)->type) { case AMove: done = MoveToward(pieces[(*cur)->piece].coords[(*cur)->axis], (*cur)->dest, (*cur)->speed / (1000 / deltaTime)); break; case ATurn: done = TurnToward(pieces[(*cur)->piece].rot[(*cur)->axis], (*cur)->dest, (*cur)->speed / (1000 / deltaTime)); break; case ASpin: done = DoSpin(pieces[(*cur)->piece].rot[(*cur)->axis], (*cur)->dest, (*cur)->speed, (*cur)->accel, 1000 / deltaTime); break; } //Tell listeners to unblock? if (done) { UnblockAll(*cur); delete *cur; anims.erase(cur); } } if (anims.size() == 0) return -1; else return 0; }