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

Last change on this file since 346 was 346, checked in by Maciej Komosinski, 7 years ago

Each thread can use its own simulator's GenMan?

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