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

Last change on this file since 145 was 145, checked in by sz, 10 years ago

Genetics reorganization (affects ALL applications!):

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