* Improve loading performance by about 25%.
  - This is certainly not the kind of change I was aiming at, but it
    just happened to get done, so why not commit it.
  - Little point for users in this change actually, since the loading
    times get down from 15 to 11 secs or so, it's not even that
    obvious.
  - I get about 25% on my PSP. Valgrind reports 36% improvement on PC.
    I wish it was the opposite ;_;
  - Feedback welcome
This commit is contained in:
jean.chalard
2010-06-08 17:42:35 +00:00
parent dfca20c90b
commit fc9fccd93b
4 changed files with 180 additions and 216 deletions

View File

@@ -42,20 +42,20 @@ class CardPrimitive {
int has(int ability);
void setText(string value);
void setText(const string& value);
const char * getText();
void addMagicText(string value);
void addMagicText(string value, string zone);
void setName(string value);
void setName(const string& value);
const string getName() const;
const string getLCName() const;
void addType(char * type_text);
void addType(int id);
void setType(const char * type_text);
void setSubtype( string value);
void setType(const string& type_text);
void setSubtype(const string& value);
int removeType(string value, int removeAll = 0);
int removeType(int value, int removeAll = 0);
bool hasSubtype(int _subtype);

View File

@@ -109,11 +109,10 @@ private:
int countByType(const char * _type);
int countByColor(int color);
int countBySet(int setId);
int readConfLine(ifstream &file, int set_id);
int totalCards();
int randomCardId();
private:
int processConfLine(string s, MTGCard* card, CardPrimitive * primitive);
int processConfLine(string &s, MTGCard* card, CardPrimitive * primitive);
bool addCardToCollection(MTGCard * card, int setId);
CardPrimitive * addPrimitive(CardPrimitive * primitive, MTGCard * card = NULL);
};

View File

@@ -17,16 +17,13 @@ CardPrimitive::CardPrimitive(){
CardPrimitive::CardPrimitive(CardPrimitive * source){
for(map<int,int>::const_iterator it = source->basicAbilities.begin(); it != source->basicAbilities.end(); ++it){
for (map<int,int>::const_iterator it = source->basicAbilities.begin(); it != source->basicAbilities.end(); ++it)
basicAbilities[it->first] = source->basicAbilities[it->first];
}
for (size_t i = 0; i< source->types.size(); i++){
for (size_t i = 0; i< source->types.size(); ++i)
types.push_back(source->types[i]);
}
for (int i = 0; i< Constants::MTG_NB_COLORS; i++){
for (int i = 0; i< Constants::MTG_NB_COLORS; ++i)
colors[i] = source->colors[i];
}
manaCost.copy(source->getManaCost());
text = source->text;
@@ -36,9 +33,8 @@ CardPrimitive::CardPrimitive(CardPrimitive * source){
toughness = source->toughness;
magicText = source->magicText;
for(map<string,string>::const_iterator it = source->magicTexts.begin(); it != source->magicTexts.end(); ++it){
for(map<string,string>::const_iterator it = source->magicTexts.begin(); it != source->magicTexts.end(); ++it)
magicTexts[it->first] = source->magicTexts[it->first];
}
spellTargetType = source->spellTargetType;
alias = source->alias;
}
@@ -48,9 +44,8 @@ int CardPrimitive::init(){
types.clear();
for (int i = 0; i< Constants::MTG_NB_COLORS; i++){
for (int i = 0; i < Constants::MTG_NB_COLORS; ++i)
colors[i] = 0;
}
magicText = "";
magicTexts.clear();
@@ -121,11 +116,8 @@ void CardPrimitive::setColor(string _color, int removeAllOthers){
}
void CardPrimitive::setColor(int _color, int removeAllOthers){
if (removeAllOthers){
for (int i=0; i<Constants::MTG_NB_COLORS; i++){
colors[i] = 0;
}
}
if (removeAllOthers)
for (int i=0; i<Constants::MTG_NB_COLORS; i++) colors[i] = 0;
colors[_color] = 1;
}
@@ -134,11 +126,8 @@ void CardPrimitive::removeColor(int _color){
}
int CardPrimitive::getColor(){
for (int i=1; i<Constants::MTG_NB_COLORS; i++){
if (colors[i]){
return i;
}
}
for (int i=1; i<Constants::MTG_NB_COLORS; i++)
if (colors[i]) return i;
return 0;
}
@@ -149,9 +138,8 @@ int CardPrimitive::hasColor(int color){
int CardPrimitive::countColors(){
int result = 0;
for(int i=Constants::MTG_COLOR_GREEN;i<=Constants::MTG_COLOR_WHITE;i++){
if (hasColor(i)) result++;
}
for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; ++i)
if (hasColor(i)) ++result;
return result;
}
@@ -166,7 +154,7 @@ void CardPrimitive::setManaCost(string s){
}
void CardPrimitive::setType(const char * _type_text){
void CardPrimitive::setType(const string& _type_text){
setSubtype(_type_text);
}
@@ -174,9 +162,9 @@ void CardPrimitive::addType(char * _type_text){
setSubtype(_type_text);
}
void CardPrimitive::setSubtype( string value){
int id = Subtypes::subtypesList->find(value);
addType(id);
void CardPrimitive::setSubtype(const string& value){
int id = Subtypes::subtypesList->find(value);
addType(id);
}
void CardPrimitive::addType(int id){
@@ -208,7 +196,7 @@ int CardPrimitive::removeType(int id, int removeAll){
void CardPrimitive::setText( string value){
void CardPrimitive::setText(const string& value){
text = value;
}
@@ -217,21 +205,21 @@ const char * CardPrimitive::getText(){
}
void CardPrimitive::addMagicText(string value){
std::transform( value.begin(), value.end(), value.begin(),::tolower );
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
if (magicText.size()) magicText.append("\n");
magicText.append(value);
}
void CardPrimitive::addMagicText(string value, string key){
std::transform( value.begin(), value.end(), value.begin(),::tolower );
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
if (magicTexts[key].size()) magicTexts[key].append("\n");
magicTexts[key].append(value);
}
void CardPrimitive::setName( string value){
void CardPrimitive::setName(const string& value) {
name = value;
lcname = value;
std::transform( lcname.begin(), lcname.end(),lcname.begin(),::tolower );
std::transform(lcname.begin(), lcname.end(), lcname.begin(), ::tolower);
//This is a bug fix for plague rats and the "foreach ability"
//Right now we add names as types, so that they get recognized
if (lcname.at(value.length()-1) == 's') Subtypes::subtypesList->find(lcname);

View File

@@ -18,11 +18,23 @@ using std::string;
#include <time.h>
#endif
static inline int getGrade(int v) {
switch (v) {
case 'S': case 's': return Constants::GRADE_SUPPORTED;
case 'B': case 'b': return Constants::GRADE_BORDERLINE;
case 'C': case 'c': return Constants::GRADE_CRAPPY;
case 'U': case 'u': return Constants::GRADE_UNSUPPORTED;
case 'D': case 'd': return Constants::GRADE_DANGEROUS;
}
return 0;
}
//MTGAllCards
int MTGAllCards::processConfLine(string s, MTGCard *card, CardPrimitive * primitive){
if (s.size() && s[0] == '#') return 0;
size_t i = s.find_first_of("=");
if (i == string::npos){
int MTGAllCards::processConfLine(string &s, MTGCard *card, CardPrimitive * primitive){
if ('#' == s[0]) return 0;
size_t i = s.find_first_of('=');
if (i == string::npos || 0 == i){
#if defined (_DEBUG)
char buffer[4096];
sprintf(buffer, "MTGDECK: Bad Line:\n %s\n", s.c_str());
@@ -30,39 +42,41 @@ int MTGAllCards::processConfLine(string s, MTGCard *card, CardPrimitive * primit
#endif
return 0;
}
string key = s.substr(0,i);
string value = s.substr(i+1);
if (!key.size()) return 0;
switch(key[0]) {
char* key = const_cast<char*>(s.c_str()); // I know what I'm doing, let me do it
key[i] = 0;
char* val = key + i + 1;
switch (key[0]) {
case 'a':
if(key.compare( "auto")==0){
if(!primitive) primitive = NEW CardPrimitive();
primitive->addMagicText(value);
} else if(key.find("auto") == 0){
if(!primitive) primitive = NEW CardPrimitive();
primitive->addMagicText(value,key.substr(4));
} else if(key.compare( "alias")==0){
if(!primitive) primitive = NEW CardPrimitive();
primitive->alias=atoi(value.c_str());
} else if (key.compare("abilities")==0){
if(!primitive) primitive = NEW CardPrimitive();
if (0 == strcmp("auto", key)) {
if (!primitive) primitive = NEW CardPrimitive();
primitive->addMagicText(val);
} else if (0 == strncmp("auto", key, 4)) {
if (!primitive) primitive = NEW CardPrimitive();
primitive->addMagicText(val, key + 4);
} else if (0 == strcmp("alias", key)) {
if (!primitive) primitive = NEW CardPrimitive();
primitive->alias = atoi(val);
} else if (0 == strcmp("abilities", key)) {
if (!primitive) primitive = NEW CardPrimitive();
string value = val;
//Specific Abilities
std::transform( value.begin(), value.end(), value.begin(),::tolower );
while (value.size()){
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
while (value.size()) {
string attribute;
size_t found2 = value.find(",");
size_t found2 = value.find(',');
if (found2 != string::npos){
attribute = value.substr(0,found2);
value = value.substr(found2+1);
}else{
attribute = value.substr(0, found2);
value = value.substr(found2 + 1);
} else {
attribute = value;
value = "";
}
for (int j = Constants::NB_BASIC_ABILITIES-1; j >=0 ; j--){
for (int j = Constants::NB_BASIC_ABILITIES-1; j >= 0 ; --j) {
size_t found = attribute.find(Constants::MTGBasicAbilities[j]);
if (found != string::npos){
primitive->basicAbilities[j] = 1;
primitive->basicAbilities[j] = 1;
break;
}
}
@@ -71,119 +85,106 @@ int MTGAllCards::processConfLine(string s, MTGCard *card, CardPrimitive * primit
break;
case 'c': //color
if(!primitive) primitive = NEW CardPrimitive();
std::transform( value.begin(), value.end(), value.begin(),::tolower );
primitive->setColor(value,1);
if (!primitive) primitive = NEW CardPrimitive();
{
string value = val;
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
primitive->setColor(value, 1);
}
break;
case 'g': //grade
{
switch(value[0]) {
case 'S':
case 's':
currentGrade = Constants::GRADE_SUPPORTED;
break;
case 'B':
case 'b':
currentGrade = Constants::GRADE_BORDERLINE;
break;
case 'C':
case 'c':
currentGrade = Constants::GRADE_CRAPPY;
break;
case 'U':
case 'u':
currentGrade = Constants::GRADE_UNSUPPORTED;
break;
case 'D':
case 'd':
currentGrade = Constants::GRADE_DANGEROUS;
break;
}
}
currentGrade = getGrade(val[0]);
break;
case 'k': //kicker
if(!primitive) primitive = NEW CardPrimitive();
std::transform( value.begin(), value.end(), value.begin(),::tolower );
if (ManaCost * cost = primitive->getManaCost()){
cost->kicker = ManaCost::parseManaCost(value);
}
if (!primitive) primitive = NEW CardPrimitive();
if (ManaCost * cost = primitive->getManaCost())
{
string value = val;
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
cost->kicker = ManaCost::parseManaCost(value);
}
break;
case 'i': //id
if (!card) card = NEW MTGCard();
card->setMTGId(atoi(value.c_str()));
card->setMTGId(atoi(val));
break;
case 'm': //mana
if(!primitive) primitive = NEW CardPrimitive();
std::transform( value.begin(), value.end(), value.begin(),::tolower );
primitive->setManaCost(value);
{
string value = val;
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
primitive->setManaCost(value);
}
break;
case 'n': //name
case 'n': //name
if(!primitive) primitive = NEW CardPrimitive();
primitive->setName(value);
if (0 == strcmp("Bloodrock Cyclops", val))
cout << "val" << endl;
primitive->setName(val);
break;
case 'p':
if(key.compare("primitive")==0){
if(!card) card = NEW MTGCard();
map<string,CardPrimitive *>::iterator it = primitives.find(value);
if (it != primitives.end()) {
card->setPrimitive(it->second);
}
if ('r' == key[1]) { // primitive
if (!card) card = NEW MTGCard();
map<string, CardPrimitive*>::iterator it = primitives.find(val);
if (it != primitives.end()) card->setPrimitive(it->second);
} else { //power
if(!primitive) primitive = NEW CardPrimitive();
primitive->setPower (atoi(value.c_str()));
if (!primitive) primitive = NEW CardPrimitive();
primitive->setPower(atoi(val));
}
break;
case 'r': //rarity
if (!card) card = NEW MTGCard();
card->setRarity (value.c_str()[0]);
card->setRarity(val[0]);
break;
case 's': //subtype
if(!primitive) primitive = NEW CardPrimitive();
while (value.size()){
size_t found = value.find(" ");
if (found != string::npos){
primitive->setSubtype(value.substr(0,found));
value = value.substr(found+1);
}else{
while (true){
char* found = index(val, ' ');
if (found) {
string value(val, found - val);
primitive->setSubtype(value);
value = "";
val = found + 1;
}
else {
primitive->setSubtype(val);
break;
}
}
break;
case 't':
if(key.compare( "target")==0){
if(!primitive) primitive = NEW CardPrimitive();
std::transform( value.begin(), value.end(), value.begin(),::tolower );
primitive->spellTargetType=value;
}else if(key.compare( "text")==0){
if(!primitive) primitive = NEW CardPrimitive();
primitive->setText(value);
}else if (key.compare("type")==0) {
if(!primitive) primitive = NEW CardPrimitive();
while (value.size()){
size_t found = value.find(" ");
if (found != string::npos){
primitive->setType(value.substr(0,found).c_str());
value = value.substr(found+1);
}else{
primitive->setType(value.c_str());
value = "";
if (!primitive) primitive = NEW CardPrimitive();
if (0 == strcmp("target", key)) {
string value = val;
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
primitive->spellTargetType = value;
} else if (0 == strcmp("text", key))
primitive->setText(val);
else if (0 == strcmp("type", key)) {
while (true){
char* found = index(val, ' ');
if (found) {
string value(val, found - val);
primitive->setType(value);
val = found + 1;
}
else {
primitive->setType(val);
break;
}
}
}else if(key.compare("toughness")==0){
if(!primitive) primitive = NEW CardPrimitive();
primitive->setToughness(atoi(value.c_str()));
}
else if (0 == strcmp("toughness", key))
primitive->setToughness(atoi(val));
break;
default:
string error = "MTGDECK Parsing Error:" + s + "\n";
OutputDebugString(error.c_str());
@@ -214,14 +215,44 @@ void MTGAllCards::init(){
int MTGAllCards::load(const char * config_file, const char * set_name,int autoload){
conf_read_mode = 0;
int set_id = 0;
if (set_name) set_id = setlist.Add(set_name);
const int set_id = set_name ? setlist.Add(set_name) : 0;
MTGSetInfo *si = setlist.getInfo(set_id);
std::ifstream setFile(config_file);
if (!setFile) return total_cards;
string s;
if (setFile){
while(readConfLine(setFile, set_id)){};
while (true) {
if (!std::getline(setFile, s)) return total_cards;
if (!s.size()) continue;
switch (conf_read_mode) {
case MTGAllCards::READ_ANYTHING:
if (s[0] == '['){
currentGrade = Constants::GRADE_SUPPORTED; // Default value
conf_read_mode = ('m' == s[1]) ? MTGAllCards::READ_METADATA : MTGAllCards::READ_CARD; // M for metadata.
}
continue;
case MTGAllCards::READ_METADATA:
if (s[0] == '[' && s[1] == '/') conf_read_mode = MTGAllCards::READ_ANYTHING;
else if (si) si->processConfLine(s);
continue;
case MTGAllCards::READ_CARD:
if (s[0] == '[' && s[1] == '/') {
conf_read_mode = MTGAllCards::READ_ANYTHING;
if (tempPrimitive) tempPrimitive = addPrimitive(tempPrimitive, tempCard);
if (tempCard) {
if (tempPrimitive) tempCard->setPrimitive(tempPrimitive);
addCardToCollection(tempCard, set_id);
}
tempCard = NULL;
tempPrimitive = NULL;
} else {
if (s[s.size()-1] == '\r') s.erase(s.size()-1); // Handle DOS files
processConfLine(s, tempCard, tempPrimitive);
}
continue;
}
}
return total_cards;
@@ -236,7 +267,7 @@ MTGAllCards::~MTGAllCards(){
}
void MTGAllCards::destroyAllCards(){
for (map<int,MTGCard *>::iterator it = collection.begin(); it!=collection.end(); it++) delete(it->second);
collection.clear();
@@ -312,9 +343,11 @@ bool MTGAllCards::addCardToCollection(MTGCard * card, int setId){
card->setId = setId;
int newId = card->getId();
if (collection.find(newId) != collection.end()){
#if defined (_DEBUG)
char outBuf[4096];
sprintf(outBuf,"warning, card id collision! : %i\n", newId);
OutputDebugString (outBuf);
OutputDebugString(outBuf);
#endif
SAFE_DELETE(card);
return false;
}
@@ -328,13 +361,9 @@ bool MTGAllCards::addCardToCollection(MTGCard * card, int setId){
collection[newId] = card; //Push card into collection.
MTGSetInfo * si = setlist.getInfo(setId);
if(si)
si->count(card); //Count card in set info
total_cards++;
if (si) si->count(card); //Count card in set info
++total_cards;
return true;
}
CardPrimitive * MTGAllCards::addPrimitive(CardPrimitive * primitive, MTGCard * card){
@@ -378,58 +407,6 @@ CardPrimitive * MTGAllCards::addPrimitive(CardPrimitive * primitive, MTGCard * c
return primitive;
}
int MTGAllCards::readConfLine(std::ifstream &file, int set_id){
MTGSetInfo * si = setlist.getInfo(set_id);
string s;
int result = 1;
if(!std::getline(file,s)) return 0;
if (!s.size()) return -1;
if (s[s.size()-1] == '\r') s.erase(s.size()-1); //Handle DOS files
switch(conf_read_mode) {
case MTGAllCards::READ_ANYTHING:
if (s[0] == '['){
currentGrade = Constants::GRADE_SUPPORTED; //default value
if(s[1] == 'm'){ //M for metadata.
conf_read_mode = MTGAllCards::READ_METADATA;
}
else{
conf_read_mode = MTGAllCards::READ_CARD;
}
}
break;
case MTGAllCards::READ_METADATA:
if (s[0] == '[' && s[1] == '/'){
conf_read_mode = MTGAllCards::READ_ANYTHING;
break;
}
if(si)
si->processConfLine(s);
break;
case MTGAllCards::READ_CARD:
if (s[0] == '[' && s[1] == '/'){
conf_read_mode = MTGAllCards::READ_ANYTHING;
if (tempPrimitive) tempPrimitive = addPrimitive (tempPrimitive,tempCard);
if (tempCard){
if (tempPrimitive) tempCard->setPrimitive(tempPrimitive);
addCardToCollection(tempCard, set_id);
}
tempCard = NULL;
tempPrimitive = NULL;
}else{
processConfLine(s, tempCard, tempPrimitive);
}
break;
default:
break;
}
return result;
}
MTGCard * MTGAllCards::getCardById(int id){
map<int, MTGCard *>::iterator it = collection.find(id);
@@ -463,7 +440,7 @@ MTGCard * MTGAllCards::getCardByName(string name){
string cardName = c->data->name;
std::transform(cardName.begin(), cardName.end(), cardName.begin(),::tolower );
if (cardName.compare(name) == 0) return c;
}
return NULL;
}
@@ -660,7 +637,7 @@ int MTGDeck::complete() {
total_cards += 4 - n;
cards[id] = 4;
}
}
}
}
return 1;
}
@@ -698,7 +675,7 @@ int MTGDeck::save(){
if (meta_name.size()){
file << "#NAME:" << meta_name << '\n';
}
if (meta_desc.size()){
size_t found = 0;
string desc= meta_desc;
@@ -748,23 +725,23 @@ MTGSetInfo* MTGSets::randomSet(int blockId, int atleast){
char * unlocked = (char *)calloc(size(),sizeof(char));
int attempts = 50;
//Figure out which sets are available.
for (int i = 0; i < size(); i++){
for (int i = 0; i < size(); i++){
unlocked[i] = options[Options::optionSet(i)].number;
}
//No luck randomly. Now iterate from a random location.
int a = 0, iter = 0;
while(iter < 3){
a = rand()%size();
a = rand()%size();
for(int i=a;i<size();i++){
if(unlocked[i]
if(unlocked[i]
&& (blockId == -1 || setinfo[i]->block == blockId)
&& (atleast == -1 || setinfo[i]->totalCards() >= atleast)){
free(unlocked);
return setinfo[i];
return setinfo[i];
}
}
for(int i=0;i<a;i++){
if(unlocked[i]
if(unlocked[i]
&& (blockId == -1 || setinfo[i]->block == blockId)
&& (atleast == -1 || setinfo[i]->totalCards() >= atleast)){
free(unlocked);
@@ -789,7 +766,7 @@ int MTGSets::Add(const char * name){
MTGSetInfo* s = NEW MTGSetInfo(name);
setinfo.push_back(s);
setid = (int) setinfo.size();
return setid - 1;
}
@@ -818,7 +795,7 @@ int MTGSets::findBlock(string s){
if(b.compare(comp) == 0) return i;
}
blocks.push_back(s);
blocks.push_back(s);
return ((int) blocks.size()) -1;
}
@@ -892,7 +869,7 @@ void MTGSetInfo::count(MTGCard*c){
counts[MTGSetInfo::LAND]++;
break;
}
counts[MTGSetInfo::TOTAL_CARDS]++;
}
@@ -901,7 +878,7 @@ int MTGSetInfo::totalCards(){
}
string MTGSetInfo::getName(){
if(name.size())
if(name.size())
return _(name); //Pretty name is translated.
return id; //Ugly name is not.
}