From 77847ec549decd46a49e58682b2504c462de64f0 Mon Sep 17 00:00:00 2001
From: Paolo Capriotti
Date: Tue, 7 Aug 2007 17:58:10 +0200
Subject: [PATCH] DropAnimatorMixin::updatePool compares actual pool with the
graphical pool.
This change mimics what happens with BaseAnimator::warp. The advantages are:
* In case of animator bugs, the pool can be fixed with a call to updatePool.
* The code is slightly longer, but more readable.
* This should work with any variant, as long as the pool is wrappable by
WrappedPool.
---
src/hlvariant/dropanimator.h | 81 ++++++++++++++++++++++++++++----------------
1 file changed, 51 insertions(+), 30 deletions(-)
diff --git a/src/hlvariant/dropanimator.h b/src/hlvariant/dropanimator.h
index 6cf68bd..cc111e7 100644
--- a/src/hlvariant/dropanimator.h
+++ b/src/hlvariant/dropanimator.h
@@ -13,6 +13,8 @@
#define HLVARIANT__DROPANIMATOR_H
#include "animationfactory.h"
+#include "namedsprite.h"
+#include "common.h"
namespace HLVariant {
@@ -46,37 +48,50 @@ template
void DropAnimatorMixin::updatePool(const GameState& final) {
for(int color = 0; color < 2; color++) {
typename Piece::Color c = static_cast(color);
- const typename GameState::Pool::RawData& before = m_cinterface->position()->pools().pool(c).rawData();
- const typename GameState::Pool::RawData& after = final.pools().pool(c).rawData();
- typename GameState::Pool::RawData::const_iterator before_it = before.begin();
- typename GameState::Pool::RawData::const_iterator after_it = after.begin();
-
- int pos = 0;
-
- // oh, a nice bunch of write-only magic shit
- while (before_it != before.end() || after_it != after.end()) {
- bool skip_after = (after_it == after.end() || (before_it != before.end()
- && before_it->first < after_it->first ));
- bool skip_before = (before_it == before.end() || (after_it != after.end()
- && after_it->first < before_it->first ));
- int na = skip_after ? 0 : after_it->second;
- int nb = skip_before ? 0 : before_it->second;
-
- if (nb < na) {
- for(int i = nb; i < na; i++)
- m_cinterface->insertPoolPiece(color, pos + (i - nb), Piece(c, after_it->first) );
+ const typename GameState::Pool pool = final.pools().pool(c);
+ const int n = pool.size();
+
+ for (int index = 0; index < n; ) {
+ // precondition: pool and graphical pool match up to index
+
+ // no more sprites on the graphical pool
+ if (index >= m_cinterface->poolSize(color)) {
+ // add extra sprites
+ for (int i = index; i < n; i++)
+ m_cinterface->insertPoolPiece(color, i, pool.get(i));
+
+ // done
+ break;
}
- else if (na < nb) {
- for (int i = na; i < nb; i++)
- m_cinterface->removePoolSprite(color, pos);
+
+ NamedSprite sprite = m_cinterface->getPoolSprite(color, index);
+ Piece piece;
+ int i;
+
+ // find a matching piece on the pool
+ for (i = index; i < n; i++) {
+ piece = pool.get(i);
+ if (piece.name() == sprite.name())
+ break;
}
-
- if (!skip_before)
- ++before_it;
- if (!skip_after) {
- pos += after_it->second;
- ++after_it;
+
+ if (i < n) {
+ // matching piece found on the pool
+ // insert all pieces before this one on the graphical pool
+ for (int j = index; j < i; j++) {
+ m_cinterface->insertPoolPiece(color, j, piece);
+ }
+ index = i + 1;
}
+ else {
+ // no such piece found: remove it from the graphical pool
+ m_cinterface->removePoolSprite(color, index);
+ }
+ }
+
+ // remove extra pieces from the graphical pool
+ while (m_cinterface->poolSize(color) > n) {
+ m_cinterface->removePoolSprite(color, n);
}
}
}
@@ -92,6 +107,8 @@ AnimationGroupPtr DropAnimatorMixin::forward(const GameState& final, const
AnimationFactory res(m_cinterface->inner());
if (move.drop() != Piece()) {
+ NamedSprite captured = m_cinterface->takeSprite(move.to());
+
std::pair dropped = m_cinterface->droppedPoolPiece();
if (dropped.first != -1 && dropped.second != -1
&& m_cinterface->position()->pools().pool(
@@ -102,18 +119,22 @@ AnimationGroupPtr DropAnimatorMixin::forward(const GameState& final, const
NamedSprite drop = m_cinterface->takePoolSprite(dropped.first, dropped.second);
m_cinterface->setSprite(move.to(), drop);
res.addPreAnimation(Animate::move(drop, move.to()));
- return res;
}
- else {
+ else {
NamedSprite drop = m_cinterface->setPiece(move.to(), move.drop(), false);
+ drop.sprite()->raise();
res.addPreAnimation(Animate::appear(drop));
}
+
+ if (captured)
+ res.addPostAnimation(Animate::destroy(captured));
res.group()->addPostAnimation(warp(final));
}
else {
res.setGroup(Base::forward(final, move));
}
+
return res;
}
--
2.11.4.GIT