source: cpp/frams/genetics/geno.cpp @ 121

Last change on this file since 121 was 121, checked in by sz, 9 years ago

updated file headers and makefiles

  • Property svn:eol-style set to native
File size: 5.1 KB
Line 
1// This file is a part of the Framsticks GDK.
2// Copyright (C) 2002-2014  Maciej Komosinski and Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.framsticks.com/ for further information.
4
5#include "geno.h"
6#include <frams/model/model.h>
7
8SListTempl<GenoValidator*> Geno::validators;
9
10void Geno::init(const SString& genstring,char genformat,const SString& genname,const SString& comment)
11{
12refcount=1;
13owner=0;
14f0gen=0;
15mapinshift=0;
16mapoutshift=0;
17isvalid=-1;
18SString gencopy(genstring);
19if (genformat==-1)
20        { // unknown format
21        genformat='1';
22        if (genstring.charAt(0)=='/')
23                {
24                int end;
25                SString newcomment;
26                switch(genstring.charAt(1))
27                        {
28                        case '/':
29                                genformat=genstring.charAt(2);
30                                if ((end=genstring.indexOf('\n'))>=0)
31                                        {
32                                        newcomment=genstring.substr(2,end-2);
33                                        gencopy=genstring.substr(end+1);
34                                        mapinshift=end+1;
35                                        }
36                                else
37                                        {
38                                        gencopy=0;
39                                        mapinshift=genstring.len();
40                                        }
41                                break;
42                        case '*':
43                                genformat=genstring.charAt(2);
44                                if ((end=genstring.indexOf("*/"))>=0)
45                                        {
46                                        newcomment=genstring.substr(2,end-2);
47                                        gencopy=genstring.substr(end+2);
48                                        mapinshift=end+2;
49                                        }
50                                else
51                                        {
52                                        gencopy=0;
53                                        mapinshift=genstring.len();
54                                        }
55                                break;
56                        }
57                if (newcomment.len()>0)
58                        {
59                        SString token; int pos=0;
60                        if (newcomment.getNextToken(pos,token,';'))
61                        if (newcomment.getNextToken(pos,token,';'))
62                                {
63                                if (token.len()) txt=token;
64                        if (newcomment.getNextToken(pos,token,';'))
65                                if (token.len()) name=token;
66                                }
67                        }
68                }
69        }
70
71gen=gencopy;
72format=genformat;
73if (!name.len()) name=genname;
74if (!txt.len()) txt=comment;
75multiline=(strchr((const char*)gen,'\n')!=0);
76// mapoutshift...?
77}
78
79void Geno::freeF0()
80{
81if (f0gen) {delete f0gen; f0gen=0;}
82}
83
84Geno::Geno(const char *genstring,char genformat,const char *genname,const char *comment)
85{
86init(SString(genstring),genformat,SString(genname),SString(comment));
87}
88
89Geno::Geno(const SString& genstring,char genformat,const SString& genname,const SString& comment)
90{
91init(genstring,genformat,genname,comment);
92}
93
94Geno::Geno(const Geno& src)
95        :gen(src.gen),name(src.name),format(src.format),txt(src.txt),isvalid(src.isvalid),
96         f0gen(0),mapinshift(src.mapinshift),mapoutshift(src.mapinshift),
97         multiline(src.multiline),owner(0)
98{f0gen=src.f0gen?new Geno(*src.f0gen):0; refcount=1;}
99
100void Geno::operator=(const Geno& src)
101{
102freeF0();
103gen=src.gen;
104name=src.name;
105format=src.format;
106txt=src.txt;
107isvalid=src.isvalid;
108mapinshift=src.mapinshift;
109mapoutshift=src.mapinshift;
110multiline=src.multiline;
111f0gen=src.f0gen?new Geno(*src.f0gen):0;
112owner=0;
113}
114
115Geno::Geno(const SString& src)
116{
117init(src,-1,SString::empty(),SString::empty());
118}
119
120void Geno::setGene(const SString& g,char newformat)
121{
122gen=g;
123isvalid=-1;
124freeF0();
125if (newformat>=0) format=newformat;
126}
127
128void Geno::setString(const SString& g)
129{
130freeF0();
131init(g,-1,SString::empty(),SString::empty());
132}
133
134void Geno::setName(const SString& n)
135{
136name=n;
137}
138
139void Geno::setComment(const SString& c)
140{
141txt=c;
142}
143
144SString Geno::toString(void) const
145{
146SString out;
147int comment=0;
148if ((format!='1')||(comment=(txt.len()||name.len())))
149        {
150        if (multiline)
151                out+="//";
152        else
153                out+="/*";
154        out+=format;
155        if (comment)
156                {
157                if (txt.len()) {out+=";";out+=txt;}
158                if (name.len()){out+=";";out+=name;}
159                }
160        if (multiline)
161                out+="\n";
162        else
163                out+="*/";
164        }
165out+=gen;
166return out;
167}
168
169SString Geno::shortString(void) const
170{
171SString out;
172if (format!='1')
173        {
174        if (multiline)
175                out+="//";
176        else
177                out+="/*";
178        if (format==0)
179                out+="invalid";
180        else
181                out+=format;
182        if (multiline)
183                out+="\n";
184        else
185                out+="*/";
186        }
187out+=gen;
188return out;
189}
190
191int Geno::mapGenToString(int genpos) const
192{
193if (genpos>gen.len()) return -2;
194if (genpos<0) return -1;
195return mapinshift+genpos;
196}
197
198int Geno::mapStringToGen(int stringpos) const
199{
200stringpos-=mapinshift;
201if (stringpos>gen.len()) return -2;
202if (stringpos<0) return -1;
203return stringpos;
204}
205
206SString Geno::getGene(void) const {return gen;}
207SString Geno::getName(void) const {return name;}
208char Geno::getFormat(void) const {return format;}
209SString Geno::getComment(void) const {return txt;}
210
211class ModelGenoValidator: public GenoValidator
212{
213public:
214        ModelGenoValidator();
215        int testGenoValidity(Geno& g);
216};
217
218ModelGenoValidator::ModelGenoValidator()
219{
220Geno::validators+=this;
221}
222
223int ModelGenoValidator::testGenoValidity(Geno& g)
224{
225if (g.getFormat()=='0')
226        {
227        Model mod(g);
228        return mod.isValid();
229        }
230else
231        {
232        Geno f0geno=g.getConverted('0');
233        return f0geno.isValid();
234        }
235}
236
237static ModelGenoValidator default_validator;
238
239void Geno::validate()
240{
241if (isvalid>=0) return;
242if (gen.len()==0) { isvalid=0; return; }
243FOREACH(GenoValidator*,v,validators)
244        if ((isvalid=v->testGenoValidity(*this))>=0)
245                break;
246}
247
248bool Geno::isValid(void)
249{
250if (isvalid<0) validate();
251return isvalid>0;
252}
253
254Geno Geno::getConverted(char otherformat,MultiMap *m)
255{
256if (otherformat==getFormat()) return *this;
257#ifndef NO_GENOCONVMANAGER
258if ((otherformat=='0')&&(!m))
259        {
260        if (!f0gen)
261                f0gen=new Geno(GenoConvManager::globalConvert(*this,otherformat));
262        return *f0gen;
263        }
264else
265        return GenoConvManager::globalConvert(*this,otherformat,m);
266#else
267return (otherformat==getFormat())?*this:Geno(0,0,0,"GenConvManager not available");
268#endif
269}
270
271Geno::~Geno()
272{
273if (f0gen) delete f0gen;
274}
Note: See TracBrowser for help on using the repository browser.