Hid Subtypes behind MTGAllCards and added a mutex to be able to use both singleton from several threads.

This commit is contained in:
Xawotihs@gmail.com
2012-02-12 22:20:05 +00:00
parent ebc4eb331f
commit bd1afebbea
15 changed files with 74 additions and 54 deletions
+3 -3
View File
@@ -2506,13 +2506,13 @@ public:
size_t found = s.find(" "); size_t found = s.find(" ");
if (found != string::npos) if (found != string::npos)
{ {
int id = Subtypes::subtypesList->find(s.substr(0, found)); int id = MTGAllCards::findType(s.substr(0, found));
types.push_back(id); types.push_back(id);
s = s.substr(found + 1); s = s.substr(found + 1);
} }
else else
{ {
int id = Subtypes::subtypesList->find(s); int id = MTGAllCards::findType(s);
types.push_back(id); types.push_back(id);
s = ""; s = "";
} }
@@ -5066,6 +5066,6 @@ public:
void PopulateColorIndexVector(list<int>& colors, const string& colorsString, char delimiter = ','); void PopulateColorIndexVector(list<int>& colors, const string& colorsString, char delimiter = ',');
void PopulateAbilityIndexVector(list<int>& abilities, const string& abilitiesString, char delimiter = ','); void PopulateAbilityIndexVector(list<int>& abilities, const string& abilitiesString, char delimiter = ',');
void PopulateSubtypesIndexVector(list<int>& subtypes, const string& subtypesString, char delimiter = ' '); void PopulateSubtypesIndexVector(list<int>& types, const string& subtypesString, char delimiter = ' ');
#endif #endif
+31 -2
View File
@@ -7,7 +7,8 @@
#include "GameApp.h" #include "GameApp.h"
#include "WResourceManager.h" #include "WResourceManager.h"
#include <dirent.h> #include <dirent.h>
#include <Threading.h>
#include <Subtypes.h>
#include <string> #include <string>
using std::string; using std::string;
@@ -104,7 +105,6 @@ protected:
void init(); void init();
void initCounters(); void initCounters();
MTGAllCards(); MTGAllCards();
MTGAllCards(const char * config_file, const char * set_name);
~MTGAllCards(); ~MTGAllCards();
public: public:
@@ -132,11 +132,40 @@ public:
int totalCards(); int totalCards();
int randomCardId(); int randomCardId();
static int findType(string subtype, bool forceAdd = true) {
boost::mutex::scoped_lock lock(instance->mMutex);
return instance->subtypesList.find(subtype, forceAdd);
};
static int add(string value, unsigned int parentType) {
boost::mutex::scoped_lock lock(instance->mMutex);
return instance->subtypesList.add(value, parentType);
};
static string findType(unsigned int id) {
return instance->subtypesList.find(id);
};
static const vector<string>& getValuesById() {
return instance->subtypesList.getValuesById();
};
static bool isSubtypeOfType(unsigned int subtype, unsigned int type) {
return instance->subtypesList.isSubtypeOfType(subtype, type);
};
static bool isSuperType(unsigned int type) {
return instance->subtypesList.isSuperType(type);
};
static bool isType(unsigned int type) {
return instance->subtypesList.isType(type);
};
static bool isSubType(unsigned int type) {
return instance->subtypesList.isSubType(type);
};
static void loadInstance(); static void loadInstance();
static void unloadAll(); static void unloadAll();
static inline MTGAllCards* getInstance() { return instance; }; static inline MTGAllCards* getInstance() { return instance; };
private: private:
boost::mutex mMutex;
Subtypes subtypesList;
map<string, MTGCard *> mtgCardByNameCache; map<string, MTGCard *> mtgCardByNameCache;
int processConfLine(string &s, MTGCard* card, CardPrimitive * primitive); int processConfLine(string &s, MTGCard* card, CardPrimitive * primitive);
bool addCardToCollection(MTGCard * card, int setId); bool addCardToCollection(MTGCard * card, int setId);
+1 -1
View File
@@ -4,6 +4,7 @@
#include <string> #include <string>
#include <map> #include <map>
#include <vector> #include <vector>
using namespace std; using namespace std;
class Subtypes class Subtypes
@@ -37,7 +38,6 @@ protected:
vector<string> valuesById; vector<string> valuesById;
vector<unsigned int> subtypesToType; vector<unsigned int> subtypesToType;
public: public:
static Subtypes * subtypesList;
Subtypes(); Subtypes();
int find(string subtype, bool forceAdd = true); int find(string subtype, bool forceAdd = true);
string find(unsigned int id); string find(unsigned int id);
+4 -4
View File
@@ -2978,10 +2978,10 @@ ATransformer::ATransformer(GameObserver* observer, int id, MTGCardInstance * sou
if (stypes.find("allsubtypes") != string::npos || stypes.find("removecreaturesubtypes") != string::npos) if (stypes.find("allsubtypes") != string::npos || stypes.find("removecreaturesubtypes") != string::npos)
{ {
const vector<string> values = Subtypes::subtypesList->getValuesById(); const vector<string> values = MTGAllCards::getValuesById();
for (size_t i = 0; i <values.size(); ++i) for (size_t i = 0; i <values.size(); ++i)
{ {
if (!Subtypes::subtypesList->isSubtypeOfType(i,Subtypes::TYPE_CREATURE)) if (!MTGAllCards::isSubtypeOfType(i,Subtypes::TYPE_CREATURE))
continue; continue;
types.push_back(i); types.push_back(i);
@@ -3482,7 +3482,7 @@ int ALoseSubtypes::addToGame()
for (int i = ((int)_target->types.size())-1; i >= 0; --i) for (int i = ((int)_target->types.size())-1; i >= 0; --i)
{ {
int subtype = _target->types[i]; int subtype = _target->types[i];
if (Subtypes::subtypesList->isSubtypeOfType(subtype, parentType)) if (MTGAllCards::isSubtypeOfType(subtype, parentType))
{ {
storedSubtypes.push_back(subtype); storedSubtypes.push_back(subtype);
_target->removeType(subtype); _target->removeType(subtype);
@@ -4506,7 +4506,7 @@ void PopulateSubtypesIndexVector(list<int>& types, const string& subTypesStringL
for (vector<string>::iterator it = subTypesList.begin(); it != subTypesList.end(); ++it) for (vector<string>::iterator it = subTypesList.begin(); it != subTypesList.end(); ++it)
{ {
string subtype = *it; string subtype = *it;
size_t id = Subtypes::subtypesList->find(subtype); size_t id = MTGAllCards::findType(subtype);
if (id != string::npos) if (id != string::npos)
types.push_back(id); types.push_back(id);
} }
+5 -5
View File
@@ -55,7 +55,7 @@ void CardDescriptor::setisMultiColored(int w)
void CardDescriptor::setNegativeSubtype(string value) void CardDescriptor::setNegativeSubtype(string value)
{ {
int id = Subtypes::subtypesList->find(value); int id = MTGAllCards::findType(value);
addType(-id); addType(-id);
} }
@@ -91,7 +91,7 @@ MTGCardInstance * CardDescriptor::match_or(MTGCardInstance * card)
if (types[i] >= 0) if (types[i] >= 0)
{ {
if (card->hasSubtype(types[i]) || (Subtypes::subtypesList->find(card->getLCName(), false) == types[i])) if (card->hasSubtype(types[i]) || (MTGAllCards::findType(card->getLCName(), false) == types[i]))
{ {
found = 1; found = 1;
break; break;
@@ -99,7 +99,7 @@ MTGCardInstance * CardDescriptor::match_or(MTGCardInstance * card)
} }
else else
{ {
if (!card->hasSubtype(-types[i]) && (Subtypes::subtypesList->find(card->getLCName(), false) != -types[i])) if (!card->hasSubtype(-types[i]) && (MTGAllCards::findType(card->getLCName(), false) != -types[i]))
{ {
found = 1; found = 1;
break; break;
@@ -142,14 +142,14 @@ MTGCardInstance * CardDescriptor::match_and(MTGCardInstance * card)
{ {
if (types[i] >= 0) if (types[i] >= 0)
{ {
if (!card->hasSubtype(types[i]) && !(Subtypes::subtypesList->find(card->getLCName(), false) == types[i])) if (!card->hasSubtype(types[i]) && !(MTGAllCards::findType(card->getLCName(), false) == types[i]))
{ {
match = NULL; match = NULL;
} }
} }
else else
{ {
if (card->hasSubtype(-types[i]) || (Subtypes::subtypesList->find(card->getLCName(), false) == -types[i])) if (card->hasSubtype(-types[i]) || (MTGAllCards::findType(card->getLCName(), false) == -types[i]))
{ {
match = NULL; match = NULL;
} }
+4 -4
View File
@@ -544,12 +544,12 @@ void CardGui::AlternateRender(MTGCard * card, const Pos& pos)
} }
else else
{ {
s += _(Subtypes::subtypesList->find(card->data->types[i])); s += _(MTGAllCards::findType(card->data->types[i]));
s += _(" - "); s += _(" - ");
} }
} }
if (card->data->types.size()) if (card->data->types.size())
s += _(Subtypes::subtypesList->find(card->data->types[0])); s += _(MTGAllCards::findType(card->data->types[0]));
else else
{ {
DebugTrace("Typeless card: " << setlist[card->setId].c_str() << card->data->getName() << card->getId()); DebugTrace("Typeless card: " << setlist[card->setId].c_str() << card->data->getName() << card->getId());
@@ -876,12 +876,12 @@ void CardGui::TinyCropRender(MTGCard * card, const Pos& pos, JQuad * quad)
} }
else else
{ {
s += _(Subtypes::subtypesList->find(card->data->types[i])); s += _(MTGAllCards::findType(card->data->types[i]));
s += _(" - "); s += _(" - ");
} }
} }
if (card->data->types.size()) if (card->data->types.size())
s += _(Subtypes::subtypesList->find(card->data->types[0])); s += _(MTGAllCards::findType(card->data->types[0]));
else else
{ {
DebugTrace("Typeless card: " << setlist[card->setId].c_str() << card->data->getName() << card->getId()); DebugTrace("Typeless card: " << setlist[card->setId].c_str() << card->data->getName() << card->getId());
+6 -6
View File
@@ -209,13 +209,13 @@ void CardPrimitive::setSubtype(const string& value)
int parentType = 0; int parentType = 0;
for (size_t i = 0; i < types.size(); ++i) for (size_t i = 0; i < types.size(); ++i)
{ {
if (Subtypes::subtypesList->isType(types[i])) if (MTGAllCards::isType(types[i]))
{ {
parentType = types[i]; parentType = types[i];
break; break;
} }
} }
int id = Subtypes::subtypesList->add(value, parentType); int id = MTGAllCards::add(value, parentType);
addType(id); addType(id);
} }
@@ -230,7 +230,7 @@ void CardPrimitive::addType(int id)
int CardPrimitive::removeType(string value, int removeAll) int CardPrimitive::removeType(string value, int removeAll)
{ {
int id = Subtypes::subtypesList->find(value); int id = MTGAllCards::findType(value);
return removeType(id, removeAll); return removeType(id, removeAll);
} }
@@ -335,19 +335,19 @@ bool CardPrimitive::hasSubtype(int _subtype)
bool CardPrimitive::hasType(const char * _type) bool CardPrimitive::hasType(const char * _type)
{ {
int id = Subtypes::subtypesList->find(_type); int id = MTGAllCards::findType(_type);
return hasType(id); return hasType(id);
} }
bool CardPrimitive::hasSubtype(const char * _subtype) bool CardPrimitive::hasSubtype(const char * _subtype)
{ {
int id = Subtypes::subtypesList->find(_subtype); int id = MTGAllCards::findType(_subtype);
return hasType(id); return hasType(id);
} }
bool CardPrimitive::hasSubtype(const string& _subtype) bool CardPrimitive::hasSubtype(const string& _subtype)
{ {
int id = Subtypes::subtypesList->find(_subtype); int id = MTGAllCards::findType(_subtype);
return hasType(id); return hasType(id);
} }
-2
View File
@@ -311,8 +311,6 @@ void GameApp::Destroy()
DeckManager::EndInstance(); DeckManager::EndInstance();
DeckStats::EndInstance(); DeckStats::EndInstance();
SAFE_DELETE(Subtypes::subtypesList);
stopMusic(); stopMusic();
Translator::EndInstance(); Translator::EndInstance();
+1 -1
View File
@@ -2008,7 +2008,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
vector<string> splitLoseTypes = parseBetween(s, "losesubtypesof(", ")"); vector<string> splitLoseTypes = parseBetween(s, "losesubtypesof(", ")");
if (splitLoseTypes.size()) if (splitLoseTypes.size())
{ {
int parentType = Subtypes::subtypesList->find(splitLoseTypes[1]); int parentType = MTGAllCards::findType(splitLoseTypes[1]);
return NEW ALoseSubtypes(observer, id, card, target, parentType); return NEW ALoseSubtypes(observer, id, card, target, parentType);
} }
+8 -8
View File
@@ -178,10 +178,10 @@ void MTGCardInstance::initMTGCI()
if (basicAbilities[(int)Constants::CHANGELING]) if (basicAbilities[(int)Constants::CHANGELING])
{//if the card is a changeling, it gains all creature subtypes {//if the card is a changeling, it gains all creature subtypes
const vector<string> values = Subtypes::subtypesList->getValuesById(); const vector<string> values = MTGAllCards::getValuesById();
for (size_t i = 0; i < values.size(); ++i) for (size_t i = 0; i < values.size(); ++i)
{ {
if (!Subtypes::subtypesList->isSubtypeOfType(i,Subtypes::TYPE_CREATURE)) if (!MTGAllCards::isSubtypeOfType(i,Subtypes::TYPE_CREATURE))
continue; continue;
//Don' want to send any event to the gameObserver inside of initMCGI, so calling the parent addType method instead of mine //Don' want to send any event to the gameObserver inside of initMCGI, so calling the parent addType method instead of mine
@@ -225,7 +225,7 @@ void MTGCardInstance::addType(int type)
//This is a hack for "transform", used in combination with "losesubtypes" on Basic Lands //This is a hack for "transform", used in combination with "losesubtypes" on Basic Lands
//See removeType below //See removeType below
if (!name.length()) if (!name.length())
setName(Subtypes::subtypesList->find(type)); setName(MTGAllCards::findType(type));
WEvent * e = NEW WEventCardChangeType(this, type, before, true); WEvent * e = NEW WEventCardChangeType(this, type, before, true);
if (observer) if (observer)
@@ -246,12 +246,12 @@ void MTGCardInstance::setType(const char * type_text)
void MTGCardInstance::setSubtype(string value) void MTGCardInstance::setSubtype(string value)
{ {
int id = Subtypes::subtypesList->find(value); int id = MTGAllCards::findType(value);
addType(id); addType(id);
} }
int MTGCardInstance::removeType(string value, int removeAll) int MTGCardInstance::removeType(string value, int removeAll)
{ {
int id = Subtypes::subtypesList->find(value); int id = MTGAllCards::findType(value);
return removeType(id, removeAll); return removeType(id, removeAll);
} }
@@ -267,7 +267,7 @@ int MTGCardInstance::removeType(int id, int removeAll)
// so if we remove a subtype "Forest", we also need to remove its name. // so if we remove a subtype "Forest", we also need to remove its name.
//This means the card might lose its name, but usually when we force remove a type, we add another one just after that. //This means the card might lose its name, but usually when we force remove a type, we add another one just after that.
//see "AddType" above which force sets a name if necessary //see "AddType" above which force sets a name if necessary
if (name.compare(Subtypes::subtypesList->find(id)) == 0) if (name.compare(MTGAllCards::findType(id)) == 0)
setName(""); setName("");
} }
WEvent * e = NEW WEventCardChangeType(this, id, before, after); WEvent * e = NEW WEventCardChangeType(this, id, before, after);
@@ -1030,7 +1030,7 @@ const string& MTGCardInstance::getSample()
for (int i = types.size() - 1; i > 0; i--) for (int i = types.size() - 1; i > 0; i--)
{ {
string type = Subtypes::subtypesList->find(types[i]); string type = MTGAllCards::findType(types[i]);
std::transform(type.begin(), type.end(), type.begin(), ::tolower); std::transform(type.begin(), type.end(), type.begin(), ::tolower);
type = type + ".wav"; type = type + ".wav";
if(getObserver() && getObserver()->getResourceManager()) if(getObserver() && getObserver()->getResourceManager())
@@ -1065,7 +1065,7 @@ const string& MTGCardInstance::getSample()
string type = ""; string type = "";
if(!types.size()) if(!types.size())
return sample; return sample;
type = Subtypes::subtypesList->find(types[0]); type = MTGAllCards::findType(types[0]);
std::transform(type.begin(), type.end(), type.begin(), ::tolower); std::transform(type.begin(), type.end(), type.begin(), ::tolower);
type.append(".wav"); type.append(".wav");
if(getObserver() && getObserver()->getResourceManager()) if(getObserver() && getObserver()->getResourceManager())
+2 -7
View File
@@ -419,12 +419,6 @@ MTGAllCards::MTGAllCards()
init(); init();
} }
MTGAllCards::MTGAllCards(const char * config_file, const char * set_name)
{
init();
load(config_file, set_name, 0);
}
MTGAllCards::~MTGAllCards() MTGAllCards::~MTGAllCards()
{ {
for (map<int, MTGCard *>::iterator it = collection.begin(); it != collection.end(); it++) for (map<int, MTGCard *>::iterator it = collection.begin(); it != collection.end(); it++)
@@ -637,6 +631,7 @@ void MTGAllCards::prefetchCardNameCache()
MTGCard * MTGAllCards::getCardByName(string nameDescriptor) MTGCard * MTGAllCards::getCardByName(string nameDescriptor)
{ {
boost::mutex::scoped_lock lock(instance->mMutex);
if (!nameDescriptor.size()) return NULL; if (!nameDescriptor.size()) return NULL;
if (nameDescriptor[0] == '#') return NULL; if (nameDescriptor[0] == '#') return NULL;
@@ -1085,7 +1080,7 @@ void MTGDeck::printDetailedDeckText(std::ofstream& file )
// Add the card's types // Add the card's types
vector<int>::iterator typeIter; vector<int>::iterator typeIter;
for ( typeIter = card->data->types.begin(); typeIter != card->data->types.end(); ++typeIter ) for ( typeIter = card->data->types.begin(); typeIter != card->data->types.end(); ++typeIter )
types << Subtypes::subtypesList->find( *typeIter ) << " "; types << MTGAllCards::findType( *typeIter ) << " ";
currentCard << trim(types.str()) << ", "; currentCard << trim(types.str()) << ", ";
types.str(""); // reset the buffer. types.str(""); // reset the buffer.
+1 -1
View File
@@ -504,7 +504,7 @@ size_t MTGGameZone::getIndex(MTGCardInstance * card)
unsigned int MTGGameZone::countByType(const char * value) unsigned int MTGGameZone::countByType(const char * value)
{ {
int result = 0; int result = 0;
int subTypeId = Subtypes::subtypesList->find(value); int subTypeId = MTGAllCards::findType(value);
for (int i = 0; i < (nb_cards); i++) for (int i = 0; i < (nb_cards); i++)
{ {
if (cards[i]->hasType(subTypeId)) if (cards[i]->hasType(subTypeId))
-2
View File
@@ -2,8 +2,6 @@
#include "Subtypes.h" #include "Subtypes.h"
Subtypes * Subtypes::subtypesList = NEW Subtypes();
Subtypes::Subtypes() Subtypes::Subtypes()
{ {
//Add the more common types, so that they can be accessed through ints //Add the more common types, so that they can be accessed through ints
+5 -5
View File
@@ -930,7 +930,7 @@ bool CardTargetChooser::equals(TargetChooser * tc)
TypeTargetChooser::TypeTargetChooser(GameObserver *observer, const char * _type, MTGCardInstance * card, int _maxtargets, bool other,bool targetMin) : TypeTargetChooser::TypeTargetChooser(GameObserver *observer, const char * _type, MTGCardInstance * card, int _maxtargets, bool other,bool targetMin) :
TargetZoneChooser(observer, card, _maxtargets, other,targetMin) TargetZoneChooser(observer, card, _maxtargets, other,targetMin)
{ {
int id = Subtypes::subtypesList->find(_type); int id = MTGAllCards::findType(_type);
nbtypes = 0; nbtypes = 0;
addType(id); addType(id);
int default_zones[] = { MTGGameZone::MY_BATTLEFIELD, MTGGameZone::OPPONENT_BATTLEFIELD }; int default_zones[] = { MTGGameZone::MY_BATTLEFIELD, MTGGameZone::OPPONENT_BATTLEFIELD };
@@ -941,7 +941,7 @@ TypeTargetChooser::TypeTargetChooser(GameObserver *observer, const char * _type,
bool other,bool targetMin) : bool other,bool targetMin) :
TargetZoneChooser(observer, card, _maxtargets, other,targetMin) TargetZoneChooser(observer, card, _maxtargets, other,targetMin)
{ {
int id = Subtypes::subtypesList->find(_type); int id = MTGAllCards::findType(_type);
nbtypes = 0; nbtypes = 0;
addType(id); addType(id);
if (nbzones == 0) if (nbzones == 0)
@@ -957,7 +957,7 @@ TypeTargetChooser::TypeTargetChooser(GameObserver *observer, const char * _type,
void TypeTargetChooser::addType(const char * _type) void TypeTargetChooser::addType(const char * _type)
{ {
int id = Subtypes::subtypesList->find(_type); int id = MTGAllCards::findType(_type);
addType(id); addType(id);
} }
@@ -978,7 +978,7 @@ bool TypeTargetChooser::canTarget(Targetable * target,bool withoutProtections)
if (card->hasSubtype(types[i])) return true; if (card->hasSubtype(types[i])) return true;
if(card->getLCName().size()) if(card->getLCName().size())
{ {
if (Subtypes::subtypesList->find(card->getLCName()) == types[i]) return true; if (MTGAllCards::findType(card->getLCName()) == types[i]) return true;
} }
} }
return false; return false;
@@ -993,7 +993,7 @@ bool TypeTargetChooser::canTarget(Targetable * target,bool withoutProtections)
for (int i = 0; i < nbtypes; i++) for (int i = 0; i < nbtypes; i++)
{ {
if (card->hasSubtype(types[i])) return true; if (card->hasSubtype(types[i])) return true;
if (Subtypes::subtypesList->find(card->name) == types[i]) return true; if (MTGAllCards::findType(card->name) == types[i]) return true;
} }
return false; return false;
} }
+1 -1
View File
@@ -2057,7 +2057,7 @@ void WGuiFilterItem::updateValue()
vector<string> stlist; vector<string> stlist;
for (int i = Subtypes::LAST_TYPE + 1;; i++) for (int i = Subtypes::LAST_TYPE + 1;; i++)
{ {
string s = Subtypes::subtypesList->find(i); string s = MTGAllCards::findType(i);
if (s == "") break; if (s == "") break;
if (s.find(" ") != string::npos) continue; if (s.find(" ") != string::npos) continue;
if (s == "Nothing") if (s == "Nothing")