Initial porting to the new component API.
[tagua/yd.git] / src / hlvariant / tagua_wrapped.h
blob7e0117478b1c509660b3c7298bbd288c41e916ef
1 #ifndef HLVARIANT__TAGUA_WRAPPED_H
2 #define HLVARIANT__TAGUA_WRAPPED_H
4 #include "movefactory.h"
5 #include "nopool.h"
6 #include "variantdata.h"
8 #ifdef Q_CC_GNU
9 #define __FUNC__ __PRETTY_FUNCTION__
10 #else
11 #define __FUNC__ __FUNCTION__
12 #endif
14 #define MISMATCH(x,y) (std::cout << " --> Error in "<<__FUNC__<<", MISMATCH!" << std::endl \
15 << " got type " << prettyTypeName(typeid(x).name()) << std::endl \
16 << " instead of " << prettyTypeName(typeid(y).name()) << std::endl \
17 << " this is " << prettyTypeName(typeid(*this).name()) << std::endl)
19 #define DEFINE_VARIANT_FACTORY() \
20 VariantFactory* createFactory() { \
21 return new WrappedVariantFactory<Variant>; \
24 namespace HLVariant {
26 template <typename Variant> class WrappedPosition;
28 template <typename Variant>
29 class WrappedPiece : public AbstractPiece {
30 typedef typename VariantData<Variant>::Piece Piece;
32 Piece m_piece;
33 public:
34 const Piece& inner() const { return m_piece; }
36 WrappedPiece(const Piece& piece)
37 : m_piece(piece) { }
39 virtual bool equals(const PiecePtr& _other) const {
40 if (!_other) return false;
41 WrappedPiece<Variant>* other = dynamic_cast<WrappedPiece<Variant>*>(_other.get());
43 if (other)
44 return m_piece == other->inner();
45 else {
46 MISMATCH(*_other.get(),WrappedPiece<Variant>);
47 return false;
51 virtual QString name() const {
52 return m_piece.name();
55 virtual PiecePtr clone() const {
56 return PiecePtr(new WrappedPiece<Variant>(m_piece));
60 template <typename Variant>
61 class WrappedPool : public AbstractPool {
62 typedef typename VariantData<Variant>::Pool Pool;
63 typedef typename VariantData<Variant>::Piece Piece;
65 Pool& m_pool;
66 public:
67 WrappedPool(Pool& pool)
68 : m_pool(pool) { }
70 WrappedPool(const Pool& pool)
71 : m_pool(const_cast<Pool&>(pool)) {
72 // FIXME: const_cast is not necessary, here, but to avoid it
73 // we would need to change the API, adding for example an
74 // AbstractConstPool with only const functions and changing the
75 // wrapper accordingly.
78 virtual int size() {
79 return m_pool.size();
82 virtual int insert(int pref_index, const PiecePtr& _piece) {
83 if (!_piece) {
84 return m_pool.insert(pref_index, Piece());
86 else {
87 WrappedPiece<Variant>* piece = dynamic_cast<WrappedPiece<Variant>*>(_piece.get());
89 if (piece)
90 return m_pool.insert(pref_index, Piece(piece->inner()) );
91 else {
92 MISMATCH(*_piece.get(), WrappedPiece<Variant>);
93 return -1;
98 virtual PiecePtr get(int index) {
99 Piece piece = m_pool.get(index);
100 if (piece != Piece())
101 return PiecePtr(new WrappedPiece<Variant>(piece));
102 else
103 return PiecePtr();
106 virtual PiecePtr take(int index) {
107 Piece piece = m_pool.take(index);
108 if (piece != Piece())
109 return PiecePtr(new WrappedPiece<Variant>(piece));
110 else
111 return PiecePtr();
115 template <typename Variant>
116 class WrappedMove : public AbstractMove {
117 typedef typename VariantData<Variant>::LegalityCheck LegalityCheck;
118 typedef typename VariantData<Variant>::Serializer Serializer;
119 typedef typename VariantData<Variant>::Move Move;
120 typedef typename VariantData<Variant>::GameState GameState;
122 Move m_move;
123 public:
124 const Move& inner() const { return m_move; }
125 Move& inner() { return m_move; }
127 WrappedMove(const Move& move)
128 : m_move(move) { }
130 virtual QString toString(const QString& rep, const PositionPtr& _ref) const {
131 WrappedPosition<Variant>* ref = dynamic_cast<WrappedPosition<Variant>*>(_ref.get());
133 if (ref) {
134 Serializer serializer(rep);
135 return serializer.serialize(m_move, ref->inner());
137 else {
138 MISMATCH(*_ref.get(), WrappedPosition<Variant>);
139 return "$@%";
143 virtual NormalUserMove toUserMove() const {
144 typename VariantData<Variant>::MoveFactory factory;
145 return factory.toNormal(m_move);
148 virtual bool equals(const MovePtr& _other) const {
149 WrappedMove<Variant>* other = dynamic_cast<WrappedMove<Variant>*>(_other.get());
151 if (other)
152 return m_move == other->inner();
153 else {
154 MISMATCH(*_other.get(), WrappedMove<Variant>);
155 return false;
161 * Metafunction that returns a null pointer when
162 * its template argument is NoPool.
164 template <typename Variant, typename Pool>
165 struct ReturnPoolAux {
166 static PoolPtr apply(typename VariantData<Variant>::GameState& state, int player) {
167 return PoolPtr(new WrappedPool<Variant>(state.pools().pool(
168 static_cast<typename VariantData<Variant>::Piece::Color>(player))));
172 template <typename Variant>
173 struct ReturnPoolAux<Variant, NoPool> {
174 static PoolPtr apply(typename VariantData<Variant>::GameState&, int) {
175 return PoolPtr();
179 template <typename Variant>
180 struct ReturnPool {
181 static PoolPtr apply(typename VariantData<Variant>::GameState& state, int player) {
182 return ReturnPoolAux<Variant, typename VariantData<Variant>::Pool>::apply(state, player);
186 template <typename Variant>
187 class WrappedPosition : public AbstractPosition {
188 typedef typename VariantData<Variant>::LegalityCheck LegalityCheck;
189 typedef typename VariantData<Variant>::GameState GameState;
190 typedef typename VariantData<Variant>::Board Board;
191 typedef typename VariantData<Variant>::Piece Piece;
192 typedef typename VariantData<Variant>::Move Move;
193 typedef typename VariantData<Variant>::Serializer Serializer;
195 GameState m_state;
196 public:
197 const GameState& inner() const { return m_state; }
198 GameState& inner() { return m_state; }
200 WrappedPosition(const GameState& state)
201 : m_state(state) { }
203 virtual Point size() const {
204 return m_state.board().size();
207 virtual QStringList borderCoords() const {
208 return m_state.board().borderCoords();
211 virtual void setup() {
212 m_state.setup();
215 virtual PiecePtr get(const Point& p) const {
216 Piece piece = m_state.board().get(p);
217 if (piece != Piece())
218 return PiecePtr(new WrappedPiece<Variant>(piece));
219 else
220 return PiecePtr();
223 virtual void set(const Point& p, const PiecePtr& _piece) {
224 if (!_piece) {
225 m_state.board().set(p, Piece());
227 else {
228 WrappedPiece<Variant>* piece = dynamic_cast<WrappedPiece<Variant>*>(_piece.get());
230 if (piece)
231 m_state.board().set(p, piece->inner());
232 else
233 MISMATCH(*_piece.get(), WrappedPiece<Variant>);
237 virtual PoolPtr pool(int player) {
238 return ReturnPool<Variant>::apply(m_state, player);
241 virtual void copyPoolFrom(const PositionPtr&) {
242 // BROKEN
245 virtual InteractionType movable(const TurnTest& test, const Point& p) const {
246 LegalityCheck check(m_state);
247 return check.movable(test, p);
250 virtual InteractionType droppable(const TurnTest& test, int index) const {
251 LegalityCheck check(m_state);
252 return check.droppable(test, index);
255 virtual int turn() const {
256 return static_cast<int>(m_state.turn());
259 virtual void setTurn(int turn) {
260 m_state.setTurn(static_cast<typename Piece::Color>(turn));
263 virtual int previousTurn() const {
264 return static_cast<int>(m_state.previousTurn());
267 virtual void switchTurn() {
268 m_state.switchTurn();
271 virtual bool testMove(const MovePtr& _move) const {
272 if (!_move)
273 return false;
275 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
277 if (move) {
278 LegalityCheck check(m_state);
279 return check.legal(move->inner());
281 else {
282 MISMATCH(*_move.get(), WrappedMove<Variant>);
283 return false;
287 virtual void move(const MovePtr& _move) {
288 if (!_move)
289 return;
291 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
293 if (move)
294 m_state.move(move->inner());
295 else
296 MISMATCH(*_move.get(), WrappedMove<Variant>);
299 virtual PositionPtr clone() const {
300 return PositionPtr(new WrappedPosition<Variant>(m_state));
303 virtual void copyFrom(const PositionPtr& _p) {
304 // TODO: check if this is used somewhere
305 WrappedPosition<Variant>* p = dynamic_cast<WrappedPosition<Variant>*>(_p.get());
307 if (p)
308 m_state = p->inner();
309 else
310 MISMATCH(*_p.get(), WrappedPosition);
313 virtual bool equals(const PositionPtr& _other) const {
314 WrappedPosition<Variant>* other = dynamic_cast<WrappedPosition<Variant>*>(_other.get());
316 if (other)
317 return m_state == other->inner();
318 else {
319 MISMATCH(*_other.get(), WrappedPosition<Variant>);
320 return false;
324 virtual MovePtr getMove(const QString& san) const {
325 Serializer serializer("compact");
326 Move res = serializer.deserialize(san, m_state);
327 if (res.valid()) {
328 return MovePtr(new WrappedMove<Variant>(res));
330 else
331 return MovePtr();
334 virtual QString state() const {
335 return ""; // BROKEN
338 virtual PiecePtr moveHint(const MovePtr&) const {
339 return PiecePtr(); // BROKEN
342 virtual QString variant() const {
343 return Variant::m_name;
346 virtual void dump() const {
347 // BROKEN
353 #include "graphicalapi_unwrapped.h"
354 #include "icsapi_wrapped.h"
356 namespace HLVariant {
358 template <typename Variant>
359 class WrappedAnimator : public AbstractAnimator {
360 typedef typename VariantData<Variant>::GameState GameState;
361 typedef typename VariantData<Variant>::Animator Animator;
362 typedef typename VariantData<Variant>::Move Move;
364 Animator m_animator;
365 public:
366 const Animator& inner() const { return m_animator; }
368 WrappedAnimator(const Animator& animator)
369 : m_animator(animator) { }
371 virtual AnimationPtr warp(const PositionPtr& _pos) {
372 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
373 if (pos)
374 return m_animator.warp(pos->inner());
375 else {
376 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
377 return AnimationPtr();
381 virtual AnimationPtr forward(const PositionPtr& _pos, const MovePtr& _move) {
382 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
383 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
385 if (move && pos)
386 return m_animator.forward(pos->inner(), move->inner());
387 else {
388 if (!move)
389 MISMATCH(*_move.get(), WrappedMove<Variant>);
390 if (!pos)
391 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
392 return AnimationPtr();
396 virtual AnimationPtr back(const PositionPtr& _pos, const MovePtr& _move) {
397 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
398 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
400 if (move && pos)
401 return m_animator.back(pos->inner(), move->inner());
402 else {
403 if (!move)
404 MISMATCH(*_move.get(), WrappedMove<Variant>);
405 if (!pos)
406 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
407 return AnimationPtr();
414 template <typename Variant>
415 class WrappedVariantInfo : public VariantInfo {
416 typedef typename VariantData<Variant>::Animator Animator;
417 typedef typename VariantData<Variant>::GameState GameState;
418 typedef typename VariantData<Variant>::Piece Piece;
419 typedef typename VariantData<Variant>::Move Move;
420 // typedef typename VariantData<Variant>::Pool Pool;
422 Variant m_variant;
423 public:
424 virtual PositionPtr createPosition() {
425 return PositionPtr(
426 new WrappedPosition<Variant>(GameState()));
429 virtual PositionPtr createCustomPosition(const OptList&) {
430 return PositionPtr(
431 new WrappedPosition<Variant>(GameState())); // BROKEN
434 virtual void forallPieces(class PieceFunction&) {
435 // BROKEN
438 virtual int moveListLayout() const {
439 return Variant::moveListLayout();
442 virtual AnimatorPtr createAnimator(GraphicalAPI* graphical_api) {
443 return AnimatorPtr(new WrappedAnimator<Variant>(
444 Animator(
445 typename UnwrappedGraphicalAPIPtr<Variant>::type(
446 new UnwrappedGraphicalAPI<Variant>(graphical_api)))));
449 virtual MovePtr createNormalMove(const NormalUserMove& move) {
450 typename VariantData<Variant>::MoveFactory factory;
451 Move m = factory.createNormalMove(move);
452 return MovePtr(new WrappedMove<Variant>(m));
455 virtual MovePtr createDropMove(const DropUserMove& move) {
456 typename VariantData<Variant>::MoveFactory factory;
457 Move m = factory.createDropMove(move);
458 return MovePtr(new WrappedMove<Variant>(m));
461 virtual MovePtr getVerboseMove(int, const VerboseNotation&) const {
462 return MovePtr();
465 virtual bool simpleMoves() {
466 return Variant::m_simple_moves;
469 virtual QString name() const {
470 return Variant::m_name;
473 virtual QString themeProxy() const {
474 return Variant::m_theme_proxy;
477 virtual OptList positionOptions() const {
478 return m_variant.positionOptions();
481 virtual ICSAPIPtr icsAPI() const {
482 return ICSAPIPtr(ReturnICSAPI<Variant>::apply());
485 virtual ActionCollection* actions() {
486 return m_variant.actions();
489 virtual void setupMove(NormalUserMove& m) const {
490 m_variant.setupMove(m);
494 template <typename Variant>
495 class WrappedVariantFactory : public VariantFactory {
496 public:
497 virtual VariantInfo* createVariant() const {
498 return new WrappedVariantInfo<Variant>;
501 virtual QString name() const {
502 return Variant::m_name;
505 virtual QString themeProxy() const {
506 return Variant::m_theme_proxy;
509 virtual bool hidden() const {
510 return Variant::m_hidden;
516 #endif // HLVARIANT__TAGUA_WRAPPED_H