// This file is a part of Framsticks GDK library. // Copyright (C) 2002-2006 Szymon Ulatowski. See LICENSE.txt for details. // Refer to http://www.frams.alife.pl/ for further information. #include "geno.h" #include "model.h" void Geno::init(const SString& genstring,int genformat,const SString& genname,const SString& comment) { owner=0; f0gen=0; mapinshift=0; mapoutshift=0; isvalid=-1; SString gencopy(genstring); if (genformat==-1) { // unknown format genformat='1'; if (genstring.charAt(0)=='/') { int end; SString newcomment; switch(genstring.charAt(1)) { case '/': genformat=genstring.charAt(2); if ((end=genstring.indexOf('\n'))>=0) { newcomment=genstring.substr(2,end-2); gencopy=genstring.substr(end+1); mapinshift=end+1; } else { gencopy=0; mapinshift=genstring.len(); } break; case '*': genformat=genstring.charAt(2); if ((end=genstring.indexOf("*/"))>=0) { newcomment=genstring.substr(2,end-2); gencopy=genstring.substr(end+2); mapinshift=end+2; } else { gencopy=0; mapinshift=genstring.len(); } break; } if (newcomment.len()>0) { SString token; int pos=0; if (newcomment.getNextToken(pos,token,';')) if (newcomment.getNextToken(pos,token,';')) { if (token.len()) txt=token; if (newcomment.getNextToken(pos,token,';')) if (token.len()) name=token; } } } } gen=gencopy; format=genformat; if (!name.len()) name=genname; if (!txt.len()) txt=comment; multiline=(strchr((const char*)gen,'\n')!=0); // mapoutshift...? } void Geno::freeF0() { if (f0gen) {delete f0gen; f0gen=0;} } Geno::Geno(const char *genstring,int genformat,const char *genname,const char *comment) { init(SString(genstring),genformat,SString(genname),SString(comment)); } Geno::Geno(const SString& genstring,int genformat,const SString& genname,const SString& comment) { init(genstring,genformat,genname,comment); } Geno::Geno(const Geno& src) :gen(src.gen),name(src.name),format(src.format),txt(src.txt),isvalid(src.isvalid), mapinshift(src.mapinshift),mapoutshift(src.mapinshift),multiline(src.multiline), f0gen(0),owner(0) {f0gen=src.f0gen?new Geno(*src.f0gen):0;} void Geno::operator=(const Geno& src) { freeF0(); gen=src.gen; name=src.name; format=src.format; txt=src.txt; isvalid=src.isvalid; mapinshift=src.mapinshift; mapoutshift=src.mapinshift; multiline=src.multiline; f0gen=src.f0gen?new Geno(*src.f0gen):0; owner=0; } Geno::Geno(const SString& src) { init(src,-1,SString::empty,SString::empty); } void Geno::setGene(const SString& g,int newformat) { gen=g; isvalid=-1; freeF0(); if (newformat>=0) format=newformat; } void Geno::setString(const SString& g) { freeF0(); init(g,-1,SString::empty,SString::empty); } void Geno::setName(const SString& n) { name=n; } void Geno::setComment(const SString& c) { txt=c; } SString Geno::toString(void) { SString out; int comment=0; if ((format!='1')||(comment=(txt.len()||name.len()))) { if (multiline) out+="//"; else out+="/*"; out+=format; if (comment) { if (txt.len()) {out+=";";out+=txt;} if (name.len()){out+=";";out+=name;} } if (multiline) out+="\n"; else out+="*/"; } out+=gen; return out; } SString Geno::shortString(void) { SString out; if (format!='1') { if (multiline) out+="//"; else out+="/*"; out+=format; if (multiline) out+="\n"; else out+="*/"; } out+=gen; return out; } int Geno::mapGenToString(int genpos) const { if (genpos>gen.len()) return -2; if (genpos<0) return -1; return mapinshift+genpos; } int Geno::mapStringToGen(int stringpos) const { stringpos-=mapinshift; if (stringpos>gen.len()) return -2; if (stringpos<0) return -1; return stringpos; } SString Geno::getGene(void) const {return gen;} SString Geno::getName(void) const {return name;} int Geno::getFormat(void) const {return format;} SString Geno::getComment(void) const {return txt;} void Geno::validate() { if (isvalid>=0) return; if (gen.len()==0) { isvalid=0; return; } if (getFormat()=='0') { Model mod(*this); isvalid=mod.isValid(); } else { Geno f0geno=getConverted('0'); f0geno.validate(); isvalid=f0geno.isvalid; } } int Geno::isValid(void) { if (isvalid<0) validate(); return isvalid; } Geno Geno::getConverted(int otherformat,MultiMap *m) { if (otherformat==getFormat()) return *this; #ifndef NO_GENOCONVMANAGER if ((otherformat=='0')&&(!m)) { if (!f0gen) f0gen=new Geno(GenoConvManager::globalConvert(*this,otherformat)); return *f0gen; } else return GenoConvManager::globalConvert(*this,otherformat,m); #else return (otherformat==getFormat())?*this:Geno(0,0,0,"GenConvManager not available"); #endif } Geno::~Geno() { if (f0gen) delete f0gen; }