diff --git a/projects/mtg/include/CardSelector.h b/projects/mtg/include/CardSelector.h index d602517d9..2351a8d73 100644 --- a/projects/mtg/include/CardSelector.h +++ b/projects/mtg/include/CardSelector.h @@ -29,52 +29,75 @@ struct LimitorFunctor template class ObjectSelector : public GuiLayer { - public: - typedef enum { - nullZone, handZone, playZone - } SelectorZone; - struct SelectorMemory - { - T* object; - float x, y; - SelectorMemory(T* object) : object(object) { if (object) { x = object->x; y = object->y; } }; - SelectorMemory() { object = NULL; x = y = 0; }; - }; +public: + typedef enum { + nullZone, handZone, playZone + } SelectorZone; + struct SelectorMemory + { + T* object; + float x, y; + SelectorMemory(T* object) : object(object) { if (object) { x = object->x; y = object->y; } }; + SelectorMemory() { object = NULL; x = y = 0; }; + }; - protected: - vector cards; - T* active; - DuelLayers* duel; - LimitorFunctor* limitor; - Pos bigpos; - map lasts; - stack< pair*, SelectorZone> > limitorStack; - stack memoryStack; +protected: + vector cards; + T* active; + DuelLayers* duel; + LimitorFunctor* limitor; + Pos bigpos; + map lasts; + stack< pair*, SelectorZone> > limitorStack; + stack memoryStack; - T* fetchMemory(SelectorMemory&); + T* fetchMemory(SelectorMemory&); - public: - ObjectSelector(DuelLayers*); - int bigMode; - void Add(T*); - void Remove(T*); - bool CheckUserInput(JButton key); - bool CheckUserInput(int x, int y); - void Update(float dt); - void Render(); - void Push(); - void Pop(); +public: + ObjectSelector(DuelLayers*); + int bigMode; + void Add(T*); + void Remove(T*); + bool CheckUserInput(JButton key); + bool CheckUserInput(int x, int y); + void Update(float dt); + void Render(); + void Push(); + void Pop(); - void Limit(LimitorFunctor* limitor, SelectorZone); - void PushLimitor(); - void PopLimitor(); + void Limit(LimitorFunctor* limitor, SelectorZone); + void PushLimitor(); + void PopLimitor(); - typedef T Target; + typedef T Target; }; typedef ObjectSelector<> CardSelector; typedef LimitorFunctor Limitor; + +namespace CardSelectorSingleton +{ + /* + ** CardSelector is essentially a singleton in its usage + ** It's not enforced, but it needs to eventually migrate to the real thing + ** For now, this function will fake it out - it's up to the client caller to make sure + ** that this gets destroyed via a Terminate call (this is currently handled in DualLayers's destructor) + */ + CardSelector* Instance(); + + /* + ** Create the singleton pointer. Instance() isn't valid until this is called. + */ + CardSelector* Create(DuelLayers* inDuelLayers); + + /* + ** Teardown the singleton pointer instance. + */ + void Terminate(); +} + + struct Exp { static inline bool test(CardSelector::Target*, CardSelector::Target*); diff --git a/projects/mtg/include/DuelLayers.h b/projects/mtg/include/DuelLayers.h index ff29a8649..24f349014 100644 --- a/projects/mtg/include/DuelLayers.h +++ b/projects/mtg/include/DuelLayers.h @@ -43,7 +43,7 @@ public: int receiveEvent(WEvent * e); float RightBoundary(); - CardSelector* cs; + CardSelector* mCardSelector; }; #include "ActionLayer.h" diff --git a/projects/mtg/include/GuiAvatars.h b/projects/mtg/include/GuiAvatars.h index 5b5a9eaaa..770ce173c 100644 --- a/projects/mtg/include/GuiAvatars.h +++ b/projects/mtg/include/GuiAvatars.h @@ -15,12 +15,11 @@ class GuiAvatars : public GuiLayer GuiGraveyard* selfGraveyard, *opponentGraveyard; GuiLibrary* selfLibrary, *opponentLibrary; GuiOpponentHand *opponentHand; - CardSelector* cs; GuiAvatar* active; public: - GuiAvatars(CardSelector*); + GuiAvatars(); ~GuiAvatars(); GuiAvatar* GetSelf(); diff --git a/projects/mtg/include/GuiHand.h b/projects/mtg/include/GuiHand.h index fe782385e..106401830 100644 --- a/projects/mtg/include/GuiHand.h +++ b/projects/mtg/include/GuiHand.h @@ -35,10 +35,9 @@ class GuiHand : public GuiLayer const MTGHand* hand; JQuad *back; vector cards; - CardSelector* cs; public: - GuiHand(CardSelector* cs, MTGHand* hand); + GuiHand(MTGHand* hand); ~GuiHand(); void Update(float dt); bool isInHand(CardView*); @@ -49,7 +48,7 @@ class GuiHand : public GuiLayer class GuiHandOpponent : public GuiHand { public: - GuiHandOpponent(CardSelector* cs, MTGHand* hand); + GuiHandOpponent(MTGHand* hand); virtual void Render(); virtual int receiveEventPlus(WEvent* e); virtual int receiveEventMinus(WEvent* e); @@ -66,7 +65,7 @@ class GuiHandSelf : public GuiHand Pos backpos; public: - GuiHandSelf(CardSelector* cs, MTGHand* hand); + GuiHandSelf(MTGHand* hand); ~GuiHandSelf(); virtual int receiveEventPlus(WEvent* e); virtual int receiveEventMinus(WEvent* e); diff --git a/projects/mtg/include/GuiPlay.h b/projects/mtg/include/GuiPlay.h index fa64eaba7..9ebd35121 100644 --- a/projects/mtg/include/GuiPlay.h +++ b/projects/mtg/include/GuiPlay.h @@ -71,13 +71,12 @@ class GuiPlay : public GuiLayer BattleField battleField; Lands selfLands, opponentLands; Spells selfSpells, opponentSpells; - CardSelector* cs; iterator end_spells; vector cards; public: - GuiPlay(GameObserver*, CardSelector*); + GuiPlay(GameObserver*); ~GuiPlay(); virtual void Render(); void Replace(); diff --git a/projects/mtg/src/ActionStack.cpp b/projects/mtg/src/ActionStack.cpp index cf2b68620..4adc90954 100644 --- a/projects/mtg/src/ActionStack.cpp +++ b/projects/mtg/src/ActionStack.cpp @@ -83,8 +83,7 @@ void Interruptible::Render(MTGCardInstance * source, JQuad * targetQuad, string } if (bigQuad){ - GameObserver * game = GameObserver::GetInstance(); - int showMode = game->mLayers->cs->bigMode; + int showMode = CardSelectorSingleton::Instance()->bigMode; Pos pos = Pos(CardGui::BigWidth / 2, CardGui::BigHeight / 2 - 10, 1.0, 0.0, 220); switch(showMode){ case BIG_MODE_SHOW: diff --git a/projects/mtg/src/CardDisplay.cpp b/projects/mtg/src/CardDisplay.cpp index fda20618d..5d0a9fd34 100644 --- a/projects/mtg/src/CardDisplay.cpp +++ b/projects/mtg/src/CardDisplay.cpp @@ -217,7 +217,7 @@ void CardDisplay::Render(){ Pos pos = Pos(CardGui::BigWidth / 2, CardGui::BigHeight / 2 - 10, 1.0, 0.0, 220); int showMode = BIG_MODE_SHOW; if (game){ - showMode = game->mLayers->cs->bigMode; + showMode = CardSelectorSingleton::Instance()->bigMode; pos.actY = 150; if (x < (CardGui::BigWidth / 2)) pos.actX = SCREEN_WIDTH - 10 - CardGui::BigWidth / 2; } diff --git a/projects/mtg/src/CardSelector.cpp b/projects/mtg/src/CardSelector.cpp index 7b700ba21..cb6ab7d27 100644 --- a/projects/mtg/src/CardSelector.cpp +++ b/projects/mtg/src/CardSelector.cpp @@ -1,4 +1,6 @@ #include +#include + #include "../include/PlayGuiObject.h" #include "../include/CardGui.h" #include "../include/CardSelector.h" @@ -299,3 +301,29 @@ void CardSelector::PopLimitor() { Limit(limitorStack.top().first, limitorStack.top().second); limitorStack.pop(); } + + +namespace CardSelectorSingleton +{ + static CardSelector* sCardSelectorInstance = NULL; + + CardSelector* Create(DuelLayers* inDuelLayers) + { + if (sCardSelectorInstance == NULL) + sCardSelectorInstance = NEW CardSelector(inDuelLayers); + + return sCardSelectorInstance; + } + + CardSelector* Instance() + { + assert(sCardSelectorInstance); + return sCardSelectorInstance; + } + + void Terminate() + { + SAFE_DELETE(sCardSelectorInstance); + sCardSelectorInstance = NULL; + } +} diff --git a/projects/mtg/src/DuelLayers.cpp b/projects/mtg/src/DuelLayers.cpp index 88d0e0829..d09fae5b6 100644 --- a/projects/mtg/src/DuelLayers.cpp +++ b/projects/mtg/src/DuelLayers.cpp @@ -15,7 +15,7 @@ void DuelLayers::init(){ GameObserver* go = GameObserver::GetInstance(); - cs = NEW CardSelector(this); + mCardSelector = CardSelectorSingleton::Create(this); //1 Action Layer action = NEW ActionLayer(); action->Add(NEW MTGGamePhase(action->getMaxId())); @@ -47,11 +47,11 @@ void DuelLayers::init(){ Add(stack = NEW ActionStack(go)); Add(combat = NEW GuiCombat(go)); Add(action); - Add(cs); - Add(hand = NEW GuiHandSelf(cs, go->players[0]->game->hand)); - Add(avatars = NEW GuiAvatars(cs)); - Add(NEW GuiHandOpponent(cs, go->players[1]->game->hand)); - Add(NEW GuiPlay(go, cs)); + Add(mCardSelector); + Add(hand = NEW GuiHandSelf(go->players[0]->game->hand)); + Add(avatars = NEW GuiAvatars()); + Add(NEW GuiHandOpponent(go->players[1]->game->hand)); + Add(NEW GuiPlay(go)); Add(NEW GuiPhaseBar()); Add(NEW GuiFrame()); Add(NEW GuiBackground()); @@ -69,7 +69,7 @@ void DuelLayers::CheckUserInput(int isAI){ if (avatars->CheckUserInput(key)) break; //avatars need to check their input before action (CTRL_CROSS) if (action->CheckUserInput(key)) break; if (hand->CheckUserInput(key)) break; - if (cs->CheckUserInput(key)) break; + if (CardSelectorSingleton::Instance()->CheckUserInput(key)) break; } } if(JGE::GetInstance()->GetLeftClickCoordinates(x, y)) @@ -78,7 +78,7 @@ void DuelLayers::CheckUserInput(int isAI){ { JGE::GetInstance()->LeftClickedProcessed(); } - else if (cs->CheckUserInput(x, y)) + else if (CardSelectorSingleton::Instance()->CheckUserInput(x, y)) { JGE::GetInstance()->LeftClickedProcessed(); } @@ -115,14 +115,21 @@ DuelLayers::DuelLayers() : nbitems(0) {} DuelLayers::~DuelLayers(){ int _nbitems = nbitems; nbitems = 0; - for (int i = 0; i < _nbitems; ++i){ - delete objects[i]; - objects[i] = NULL; + for (int i = 0; i < _nbitems; ++i) + { + if (objects[i] != mCardSelector) + { + delete objects[i]; + objects[i] = NULL; + } } for (size_t i = 0; i < waiters.size(); ++i) delete(waiters[i]); Trash::cleanup(); + + CardSelectorSingleton::Terminate(); + mCardSelector = NULL; } void DuelLayers::Add(GuiLayer * layer){ diff --git a/projects/mtg/src/GuiAvatars.cpp b/projects/mtg/src/GuiAvatars.cpp index 553f682f0..99f0d8400 100644 --- a/projects/mtg/src/GuiAvatars.cpp +++ b/projects/mtg/src/GuiAvatars.cpp @@ -5,7 +5,7 @@ #define LIB_GRAVE_OFFSET 230 -GuiAvatars::GuiAvatars(CardSelector* cs) : cs(cs), active(NULL) +GuiAvatars::GuiAvatars() : active(NULL) { Add(self = NEW GuiAvatar (SCREEN_WIDTH, SCREEN_HEIGHT, false, GameObserver::GetInstance()->players[0], GuiAvatar::BOTTOM_RIGHT, this)); @@ -22,8 +22,13 @@ GuiAvatars::GuiAvatars(CardSelector* cs) : cs(cs), active(NULL) Add(opponentGraveyard = NEW GuiGraveyard(5 + GuiAvatar::Width * 1.2 - GuiGameZone::Width / 2, 5, false, GameObserver::GetInstance()->players[1], this)); Add(opponentLibrary = NEW GuiLibrary (5 + GuiAvatar::Width *1.2 - GuiGameZone::Width / 2, 5 + GuiGameZone::Height + 5, false, GameObserver::GetInstance()->players[1], this)); - cs->Add(self); cs->Add(selfGraveyard); cs->Add(selfLibrary); - cs->Add(opponent); cs->Add(opponentGraveyard); cs->Add(opponentLibrary); cs->Add(opponentHand); + CardSelectorSingleton::Instance()->Add(self); + CardSelectorSingleton::Instance()->Add(selfGraveyard); + CardSelectorSingleton::Instance()->Add(selfLibrary); + CardSelectorSingleton::Instance()->Add(opponent); + CardSelectorSingleton::Instance()->Add(opponentGraveyard); + CardSelectorSingleton::Instance()->Add(opponentLibrary); + CardSelectorSingleton::Instance()->Add(opponentHand); selfGraveyard->alpha = selfLibrary->alpha = opponentGraveyard->alpha = opponentLibrary->alpha = opponentHand->alpha = 0; } diff --git a/projects/mtg/src/GuiHand.cpp b/projects/mtg/src/GuiHand.cpp index 6c239bfb2..a65c40a9f 100644 --- a/projects/mtg/src/GuiHand.cpp +++ b/projects/mtg/src/GuiHand.cpp @@ -25,7 +25,7 @@ bool HandLimitor::greyout(Target* t) } HandLimitor::HandLimitor(GuiHand* hand) : hand(hand) {} -GuiHand::GuiHand(CardSelector* cs, MTGHand* hand) : GuiLayer(), hand(hand), cs(cs) +GuiHand::GuiHand(MTGHand* hand) : GuiLayer(), hand(hand) { back = resources.RetrieveTempQuad("handback.png"); if(back) back->SetTextureRect(1, 0, 100, 250); @@ -51,7 +51,7 @@ bool GuiHand::isInHand(CardView* card) return (it != cards.end()); } -GuiHandOpponent::GuiHandOpponent(CardSelector* cs, MTGHand* hand) : GuiHand(cs, hand) {} +GuiHandOpponent::GuiHandOpponent(MTGHand* hand) : GuiHand(hand) {} void GuiHandOpponent::Render() { @@ -68,7 +68,7 @@ void GuiHandOpponent::Render() } } -GuiHandSelf::GuiHandSelf(CardSelector* cs, MTGHand* hand) : GuiHand(cs, hand), state(Closed), backpos(ClosedX, SCREEN_HEIGHT - 250, 1.0, 0, 255) +GuiHandSelf::GuiHandSelf(MTGHand* hand) : GuiHand(hand), state(Closed), backpos(ClosedX, SCREEN_HEIGHT - 250, 1.0, 0, 255) { limitor = NEW HandLimitor(this); if (OptionHandDirection::HORIZONTAL == options[Options::HANDDIRECTION].number) @@ -134,9 +134,9 @@ bool GuiHandSelf::CheckUserInput(JButton key) if (trigger == key) { state = (Open == state ? Closed : Open); - if (Open == state) cs->Push(); - cs->Limit(Open == state ? limitor : NULL, CardSelector::handZone); - if (Closed == state) cs->Pop(); + if (Open == state) CardSelectorSingleton::Instance()->Push(); + CardSelectorSingleton::Instance()->Limit(Open == state ? limitor : NULL, CardSelector::handZone); + if (Closed == state) CardSelectorSingleton::Instance()->Pop(); if (OptionHandDirection::HORIZONTAL == options[Options::HANDDIRECTION].number) backpos.y = Open == state ? OpenY : ClosedY; else @@ -217,7 +217,7 @@ int GuiHandSelf::receiveEventPlus(WEvent* e) card = NEW CardView(CardSelector::handZone, ev->card, ClosedRowX, 0); card->t = 6*M_PI; cards.push_back(card); - cs->Add(card); + CardSelectorSingleton::Instance()->Add(card); Repos(); return 1; } @@ -232,7 +232,7 @@ int GuiHandSelf::receiveEventMinus(WEvent* e) if (event->card->previous == (*it)->card) { CardView* cv = *it; - cs->Remove(cv); + CardSelectorSingleton::Instance()->Remove(cv); cards.erase(it); Repos(); trash(cv); diff --git a/projects/mtg/src/GuiPlay.cpp b/projects/mtg/src/GuiPlay.cpp index 305014af7..1f367c9ce 100644 --- a/projects/mtg/src/GuiPlay.cpp +++ b/projects/mtg/src/GuiPlay.cpp @@ -112,7 +112,7 @@ void GuiPlay::BattleField::Render() JRenderer::GetInstance()->FillRect(22, SCREEN_HEIGHT / 2 + 10 - height / 2, 250, height, ARGB(127, red, 0, 0)); } -GuiPlay::GuiPlay(GameObserver* game, CardSelector* cs) : game(game), cs(cs) +GuiPlay::GuiPlay(GameObserver* game) : game(game) { end_spells = cards.end(); } @@ -221,56 +221,57 @@ void GuiPlay::Update(float dt) int GuiPlay::receiveEventPlus(WEvent * e) { if (WEventZoneChange *event = dynamic_cast(e)) + { + if ((game->players[0]->inPlay() == event->to) || + (game->players[1]->inPlay() == event->to)) { - if ((game->players[0]->inPlay() == event->to) || - (game->players[1]->inPlay() == event->to)) - { - CardView * card; - if (event->card->view){ - //fix for http://code.google.com/p/wagic/issues/detail?id=462. - // We don't want a card in the hand to have an alpha of 0 - event->card->view->alpha = 255; + CardView * card; + if (event->card->view){ + //fix for http://code.google.com/p/wagic/issues/detail?id=462. + // We don't want a card in the hand to have an alpha of 0 + event->card->view->alpha = 255; - card = NEW CardView(CardSelector::playZone, event->card, *(event->card->view)); - } - else - card = NEW CardView(CardSelector::playZone, event->card, 0, 0); - cards.push_back(card); - card->t = event->card->isTapped() ? M_PI / 2 : 0; - card->alpha = 255; - cs->Add(card); - Replace(); - return 1; - } - } - else if (WEventCreatureAttacker* event = dynamic_cast(e)) - { - if (NULL != event->after) - battleField.addAttacker(event->card); - else if (NULL != event->before) - battleField.removeAttacker(event->card); - Replace(); - } - else if (dynamic_cast(e)) - { - Replace(); - } - else if (WEventCardTap* event = dynamic_cast(e)) - { - if (CardView* cv = dynamic_cast(event->card->view)) - cv->t = event->after ? M_PI / 2 : 0; + card = NEW CardView(CardSelector::playZone, event->card, *(event->card->view)); + } else - event->card->view->actT = event->after ? M_PI / 2 : 0; + card = NEW CardView(CardSelector::playZone, event->card, 0, 0); + cards.push_back(card); + card->t = event->card->isTapped() ? M_PI / 2 : 0; + card->alpha = 255; + CardSelectorSingleton::Instance()->Add(card); + Replace(); return 1; } + } + else if (WEventCreatureAttacker* event = dynamic_cast(e)) + { + if (NULL != event->after) + battleField.addAttacker(event->card); + else if (NULL != event->before) + battleField.removeAttacker(event->card); + Replace(); + } + else if (dynamic_cast(e)) + { + Replace(); + } + else if (WEventCardTap* event = dynamic_cast(e)) + { + if (CardView* cv = dynamic_cast(event->card->view)) + cv->t = event->after ? M_PI / 2 : 0; + else + event->card->view->actT = event->after ? M_PI / 2 : 0; + return 1; + } else if (WEventPhaseChange *event = dynamic_cast(e)) - { - if (Constants::MTG_PHASE_COMBATEND == event->to->id) battleField.colorFlow = -1; - } + { + if (Constants::MTG_PHASE_COMBATEND == event->to->id) battleField.colorFlow = -1; + } else if (dynamic_cast(e)) Replace(); return 0; } + int GuiPlay::receiveEventMinus(WEvent * e) { if (WEventZoneChange *event = dynamic_cast(e)) @@ -283,7 +284,7 @@ int GuiPlay::receiveEventMinus(WEvent * e) if (event->card->previous && event->card->previous->attacker) battleField.removeAttacker(event->card->previous); else if (event->card->attacker) battleField.removeAttacker(event->card); CardView* cv = *it; - cs->Remove(cv); + CardSelectorSingleton::Instance()->Remove(cv); cards.erase(it); trash(cv); Replace(); diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index 75f9704b3..f7dcf579a 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -725,12 +725,11 @@ int MTGAttackRule::reactToClick(MTGCardInstance * card){ //Graphically select the next card that can attack if(!card->isAttacker()){ - CardSelector * cs = game->mLayers->cs; - cs->PushLimitor(); - cs->Limit(this,CardSelector::playZone); - cs->CheckUserInput(JGE_BTN_RIGHT); - cs->Limit(NULL,CardSelector::playZone); - cs->PopLimitor(); + CardSelectorSingleton::Instance()->PushLimitor(); + CardSelectorSingleton::Instance()->Limit(this,CardSelector::playZone); + CardSelectorSingleton::Instance()->CheckUserInput(JGE_BTN_RIGHT); + CardSelectorSingleton::Instance()->Limit(NULL,CardSelector::playZone); + CardSelectorSingleton::Instance()->PopLimitor(); } card->toggleAttacker(); return 1;