From 0bf83b6bf58249817cb919636069f4f59bf73910 Mon Sep 17 00:00:00 2001 From: "wagic.the.homebrew@gmail.com" Date: Sat, 26 Sep 2009 14:25:29 +0000 Subject: [PATCH] Erwan - fixed a bug with Flagstones of Trokair. There was no easy fix (cloned objects deleting stuff from their parents...) and I ended up using a "garbage collect at end of turn" technique the way I did with the ActionStack. As a result, the memory print of a turn will become bigger, and even more bugs might occur at the end of a turn... I'm ready to discuss this, although I think it's the best solution (in terms of result/amount of work) given the way abilities work right now - Test suite now gives the number of failed/success at the end of the tests --- projects/mtg/bin/Res/sets/TSP/_cards.dat | 13 -------- projects/mtg/bin/Res/sets/TSP/todo.dat | 13 ++++++++ projects/mtg/bin/Res/test/_tests.txt | 1 + projects/mtg/include/ActionLayer.h | 3 ++ projects/mtg/include/AllAbilities.h | 4 +-- projects/mtg/include/TestSuiteAI.h | 1 + projects/mtg/src/ActionLayer.cpp | 24 +++++++++++++- projects/mtg/src/GameObserver.cpp | 10 ++---- projects/mtg/src/GameStateDuel.cpp | 40 ++++++++++++++---------- projects/mtg/src/TestSuiteAI.cpp | 8 ++++- 10 files changed, 76 insertions(+), 41 deletions(-) diff --git a/projects/mtg/bin/Res/sets/TSP/_cards.dat b/projects/mtg/bin/Res/sets/TSP/_cards.dat index 2f8ed61b8..eee34277b 100644 --- a/projects/mtg/bin/Res/sets/TSP/_cards.dat +++ b/projects/mtg/bin/Res/sets/TSP/_cards.dat @@ -94,19 +94,6 @@ type=Instant mana={2}{U} [/card] [card] -id=108901 -name=Bogardan Rager -mana={5}{R} -type=Creature -subtype=Elemental -power=3 -toughness=4 -text=Flash (You may play this spell any time you could play an instant.) When Bogardan Rager comes into play, target creature gets +4/+0 until end of turn. -abilities=flash -auto=4/0 target(creature) -rarity=C -[/card] -[card] id=109697 name=Bonesplitter Sliver mana={3}{R} diff --git a/projects/mtg/bin/Res/sets/TSP/todo.dat b/projects/mtg/bin/Res/sets/TSP/todo.dat index a09acb47e..a478ae0c4 100644 --- a/projects/mtg/bin/Res/sets/TSP/todo.dat +++ b/projects/mtg/bin/Res/sets/TSP/todo.dat @@ -109,6 +109,19 @@ text=Flash Flying When Bogardan Hellkite comes into play, it deals 5 damage divi rarity=R [/card] [card] +id=108901 +name=Bogardan Rager +mana={5}{R} +type=Creature +subtype=Elemental +power=3 +toughness=4 +text=Flash (You may play this spell any time you could play an instant.) When Bogardan Rager comes into play, target creature gets +4/+0 until end of turn. +abilities=flash +auto=4/0 target(creature) +rarity=C +[/card] +[card] id=118895 name=Brine Elemental mana={4}{U}{U} diff --git a/projects/mtg/bin/Res/test/_tests.txt b/projects/mtg/bin/Res/test/_tests.txt index 5f1fd0d0f..3f51f74ae 100644 --- a/projects/mtg/bin/Res/test/_tests.txt +++ b/projects/mtg/bin/Res/test/_tests.txt @@ -94,6 +94,7 @@ dross_harvester.txt elvish_piper.txt elvish_promenade.txt emblem_of_the_warmind.txt +flagstones.txt farhaven_elf.txt fastbond.txt fastbond2.txt diff --git a/projects/mtg/include/ActionLayer.h b/projects/mtg/include/ActionLayer.h index 80cbd7797..7cfdb97dc 100644 --- a/projects/mtg/include/ActionLayer.h +++ b/projects/mtg/include/ActionLayer.h @@ -18,6 +18,7 @@ class WEvent; class ActionLayer: public GuiLayer, public JGuiListener{ public: + vector garbage; Targetable * menuObject; SimpleMenu * abilitiesMenu; int stuffHappened; @@ -42,6 +43,8 @@ class ActionLayer: public GuiLayer, public JGuiListener{ void doReactTo(int menuIndex); TargetChooser * getCurrentTargetChooser(); MTGAbility * getAbility(int type); + int moveToGarbage(ActionElement * e); + int cleanGarbage(); }; diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 41cca714d..32b65bee2 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -215,9 +215,9 @@ public: } ~MultiAbility(){ - if (!isClone){ + if (!isClone){ vector::size_type sz = abilities.size(); - for (unsigned int i = 0; i < sz; i++){ + for (size_t i = 0; i < sz; i++){ delete abilities[i]; } } diff --git a/projects/mtg/include/TestSuiteAI.h b/projects/mtg/include/TestSuiteAI.h index 92fd75248..a90d7796d 100644 --- a/projects/mtg/include/TestSuiteAI.h +++ b/projects/mtg/include/TestSuiteAI.h @@ -60,6 +60,7 @@ class TestSuite{ string files[1024]; int nbfiles; int currentfile; + int nbFailed, nbTests; int load(const char * filename); TestSuite(const char * filename,MTGAllCards* _collection); void initGame(); diff --git a/projects/mtg/src/ActionLayer.cpp b/projects/mtg/src/ActionLayer.cpp index f7b71b109..50ed44c4d 100644 --- a/projects/mtg/src/ActionLayer.cpp +++ b/projects/mtg/src/ActionLayer.cpp @@ -14,6 +14,27 @@ MTGAbility* ActionLayer::getAbility(int type){ return NULL; } +int ActionLayer::moveToGarbage(ActionElement * e){ + int i = getIndexOf(e); + if (i != -1){ + e->destroy(); + mObjects.erase(mObjects.begin()+i); + mCount--; + garbage.push_back(e); + return 1; + } + return 0; + +} + +int ActionLayer::cleanGarbage(){ + for (size_t i = 0; i < garbage.size(); ++i){ + delete(garbage[i]); + } + garbage.clear(); + return 1; +} + int ActionLayer::reactToClick(ActionElement * ability, MTGCardInstance * card){ int result = ability->reactToClick(card); if (result) stuffHappened = 1; @@ -72,7 +93,7 @@ void ActionLayer::Update(float dt){ if (mObjects[i]!= NULL){ ActionElement * currentAction = (ActionElement *)mObjects[i]; if (currentAction->testDestroy()) - game->removeObserver(currentAction); + game->removeObserver(currentAction); } } int newPhase = game->getCurrentGamePhase(); @@ -254,4 +275,5 @@ void ActionLayer::ButtonPressed(int controllerid, int controlid){ ActionLayer::~ActionLayer(){ SAFE_DELETE(abilitiesMenu); + cleanGarbage(); } diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 9ee6cf3e3..f0bcc952a 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -117,6 +117,7 @@ void GameObserver::nextGamePhase(){ //Auto Hand cleaning, in case the player didn't do it himself while(currentPlayer->game->hand->nb_cards > 7) currentPlayer->game->putInGraveyard(currentPlayer->game->hand->cards[0]); + mLayers->actionLayer()->cleanGarbage(); //clean abilities history for this turn; mLayers->stackLayer()->garbageCollect(); //clean stack history for this turn; mLayers->actionLayer()->Update(0); for (int i=0; i < 2; i++){ @@ -240,13 +241,8 @@ void GameObserver::addObserver(MTGAbility * observer){ void GameObserver::removeObserver(ActionElement * observer){ - if (observer) - { - if (mLayers->actionLayer()->getIndexOf(observer) != -1){ - observer->destroy(); - mLayers->actionLayer()->Remove(observer); - } - } + if (observer)mLayers->actionLayer()->moveToGarbage(observer); + else {} //TODO log error } diff --git a/projects/mtg/src/GameStateDuel.cpp b/projects/mtg/src/GameStateDuel.cpp index 7cf14fad4..01bf9d7c1 100644 --- a/projects/mtg/src/GameStateDuel.cpp +++ b/projects/mtg/src/GameStateDuel.cpp @@ -181,31 +181,22 @@ void GameStateDuel::loadPlayer(int playerId, int decknb, int isAI){ #ifdef TESTSUITE void GameStateDuel::loadTestSuitePlayers(){ - OutputDebugString ("loading suite 1\n"); if (!testSuite) return; for (int i = 0; i < 2; i++){ SAFE_DELETE(mPlayers[i]); SAFE_DELETE(deck[i]); mPlayers[i] = NEW TestSuiteAI(testSuite, i); - OutputDebugString ("loading suite 2\n"); deck[i] = mPlayers[i]->game; } mParent->gameType = testSuite->gameType; - if (game) delete game; - game = NULL; - if (!game){ - GameObserver::Init(mPlayers, 2); - OutputDebugString ("loading suite 3\n"); - game = GameObserver::GetInstance(); - OutputDebugString ("loading suite 4\n"); - game->startGame(0,0); - OutputDebugString ("loading suite 5\n"); - - if (mParent->gameType == GAME_TYPE_MOMIR){ - game->addObserver(NEW MTGMomirRule(-1, mParent->collection)); - for (int i = 0; i < 2; i++){ - game->players[i]->life+=4; - } + SAFE_DELETE(game); + GameObserver::Init(mPlayers, 2); + game = GameObserver::GetInstance(); + game->startGame(0,0); + if (mParent->gameType == GAME_TYPE_MOMIR){ + game->addObserver(NEW MTGMomirRule(-1, mParent->collection)); + for (int i = 0; i < 2; i++){ + game->players[i]->life+=4; } } } @@ -405,6 +396,21 @@ void GameStateDuel::Render() JRenderer * r = JRenderer::GetInstance(); r->ClearScreen(ARGB(200,0,0,0)); credits->Render(); +#ifdef TESTSUITE + if (mParent->players[1] == PLAYER_TYPE_TESTSUITE){ + r->ClearScreen(ARGB(255,0,0,0)); + char buf[4096]; + int nbFailed = testSuite->nbFailed; + int nbTests = testSuite->nbTests; + if (!nbFailed){ + sprintf(buf, "All %i tests successful!", nbTests); + }else{ + sprintf(buf, "%i tests out of %i FAILED!", nbFailed, nbTests); + } + + mFont->DrawString(buf,0,SCREEN_HEIGHT/2); + } +#endif break; } case DUEL_STATE_ERROR: diff --git a/projects/mtg/src/TestSuiteAI.cpp b/projects/mtg/src/TestSuiteAI.cpp index 28afde261..f85195564 100644 --- a/projects/mtg/src/TestSuiteAI.cpp +++ b/projects/mtg/src/TestSuiteAI.cpp @@ -379,7 +379,11 @@ int TestSuite::assertGame(){ } } } - if (error) return 0; + nbTests++; + if (error) { + nbFailed++; + return 0; + } Log("==Test Succesful !=="); return 1; } @@ -391,6 +395,8 @@ TestSuite::TestSuite(const char * filename,MTGAllCards* _collection){ std::string s; nbfiles = 0; currentfile = 0; + nbFailed = 0; + nbTests = 0; int comment = 0; if(file){ while(std::getline(file,s)){