source: cpp/frams/genetics/genoconv.cpp @ 119

Last change on this file since 119 was 109, checked in by sz, 8 years ago

source reorganization (see README)
new feature added: part/joint shapes (see frams/_demos/part_shapes.cpp)

  • Property svn:eol-style set to native
File size: 4.9 KB
Line 
1// This file is a part of the Framsticks GDK library.
2// Copyright (C) 2002-2011  Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.framsticks.com/ for further information.
4
5#include <common/nonstd.h>
6
7#include <stdlib.h>
8#include <math.h>
9#include <stdio.h>
10#include <string.h>
11#include <ctype.h>
12#include <time.h>
13#include <errno.h>
14
15#include "genoconv.h"
16#include <frams/util/multimap.h>
17
18///////////////////////////////////////////////////////////////////////////
19
20GenoConvParam::GenoConvParam(GenoConvManager *g):Param(0),gcm(g)
21{
22updatetab();
23}
24
25void GenoConvParam::freetab()
26{
27if (tab) free(tab);
28tab=0;
29}
30
31const char *GenoConvParam::id(int i)
32{
33if (i>=gcm->converters.size()) return 0;
34sprintf(tmp_id,"genkonw%d",i);
35return tmp_id;
36}
37
38void GenoConvParam::updatetab()
39{
40int i;
41GenoConverter *gk;
42ParamEntry *pe;
43int ile=gcm->converters.size();
44freetab();
45tab=(ParamEntry*)calloc(2+ile,sizeof(ParamEntry));
46tab[0].id="Genetics: Conversions";
47tab[0].group=1;
48tab[0].flags=(short)ile;
49tab[0].name="gkparam:";
50gcnames.clear();
51for (i=0,pe=tab+1;gk=(GenoConverter *)gcm->converters(i);pe++,i++)
52        {
53        pe->id="?";
54        pe->group=0;
55        pe->flags=0;
56        std::string descr="f";
57        descr+=gk->in_format;
58        descr+=" -> f";
59        descr+=gk->out_format;
60        descr+=" : ";
61        descr+=gk->name;
62        gcnames.push_back(descr);
63        pe->name=descr.c_str();
64        pe->type="d 0 1";
65        pe->help=gk->info;
66        }
67pe->id=0;
68}
69
70GenoConvParam::~GenoConvParam()
71{
72freetab();
73}
74
75void *GenoConvParam::getTarget(int i)
76{
77GenoConverter *gk=(GenoConverter *)gcm->converters(i);
78return &gk->enabled;
79}
80
81GenoConvManager::GenoConvManager()
82        :param(this)
83{
84if (!globalobject) globalobject=this;
85}
86
87GenoConvManager::~GenoConvManager()
88{
89GenoConverter *gc;
90for (converters.start();gc=(GenoConverter*)converters();) delete gc;
91if (globalobject==this) globalobject=NULL;
92}
93
94GenoConvManager *GenoConvManager::globalobject=NULL;
95
96void GenoConvManager::addConverter(GenoConverter *gc)
97{
98converters+=gc;
99param.updatetab();
100}
101void GenoConvManager::removeConverter(GenoConverter *gc)
102{
103converters-=gc;
104param.updatetab();
105}
106
107GenoConverter *GenoConvManager::findConverters(SListTempl<GenoConverter*>* result,char in,char out,int enabled,char* name)
108{
109GenoConverter *gk,*retval=0;
110int i=0;
111for (;gk=(GenoConverter*)converters(i);i++)
112        {
113        if ((in!=-1)&&(in!=gk->in_format)) continue;
114        if ((out!=-1)&&(out!=gk->out_format)) continue;
115        if ((enabled!=-1)&&(enabled!=gk->enabled)) continue;
116        if ((name)&&(strcmp(name,gk->name))) continue;
117        if (!retval) {retval=gk; if (!result) break;}
118        if (result) result->append(gk);
119        }
120return retval;
121}
122
123/// write path into 'path'
124/// return the last path element (return >= path)
125/// null -> path not found
126/// @param mapavailable will receive 1 if conversion map is supported by all converters in path
127/// (can be NULL if you don't need this information)
128
129char *GenoConvManager::getPath(char in,char out,char *path,int maxlen,int *mapavailable)
130{
131if (!maxlen) return 0;
132GenoConverter *gk;
133int i=0;
134for (;gk=(GenoConverter*)converters(i);i++)
135        {
136        if ((gk->enabled)&&(gk->in_format == in))
137                {
138                *path=(char)i;
139                if (gk->out_format == out)
140                        {
141                        if (mapavailable)
142                                *mapavailable=gk->mapsupport;
143                        return path;
144                        }
145                else
146                        {
147                        int mapavail;
148                        char *ret=getPath(gk->out_format,out,path+1,maxlen-1,&mapavail);
149                        if (ret)
150                                {
151                                if (mapavailable)
152                                        *mapavailable=gk->mapsupport && mapavail;
153                                return ret;
154                                }
155                        }
156                }
157        }
158return 0;
159}
160
161char *GenoConvManager::getFormatPath(char in,char out,char *path,int maxlen,int *mapavailable)
162{
163char *ret=getPath(in,out,path,maxlen,mapavailable);
164if (ret)
165        {
166        for (char*t=path;t<=ret;t++)
167                *t=((GenoConverter*)converters(*t))->out_format;
168        }
169return ret;
170}
171
172Geno GenoConvManager::convert(Geno &in,char format,MultiMap *map)
173{
174if (in.getFormat()==format) return in;
175char path[10];
176int dep;
177char *ret;
178if (in.isInvalid()) { return Geno("",0,"","invalid genotype cannot be converted"); }
179int mapavail;
180for (dep=1;dep<(int)sizeof(path);dep++) // sogenannte iteracyjne poglebianie...
181        if (ret=getPath(in.getFormat(),format,path,dep,&mapavail)) break;
182if (!ret) { return Geno("",0,"","converter not found"); }
183if (!map) mapavail=0;
184char *t=path;
185SString tmp;
186tmp=in.getGene();
187MultiMap lastmap,tmpmap;
188int firstmap=1;
189for (;t<=ret;t++)
190        {
191        GenoConverter *gk=(GenoConverter*)converters(*t);
192        tmp=gk->convert(tmp,mapavail?&tmpmap:0);
193        if (!tmp.len())
194                {
195                char t[100];
196                sprintf(t,"f%c->f%c conversion failed (%s)",gk->in_format,gk->out_format,gk->name);
197                return Geno(0,0,0,t);
198                }
199        if (mapavail)
200                {
201                if (firstmap)
202                        {
203                        lastmap=tmpmap;
204                        firstmap=0;
205                        }
206                else
207                        {
208                        MultiMap m;
209                        m.addCombined(lastmap,tmpmap);
210                        lastmap=m;
211                        }
212                tmpmap.clear();
213                }
214        }
215if (map)
216        *map=lastmap;
217return Geno(tmp, format, in.getName(), in.getComment());
218}
219
220Geno GenoConvManager::globalConvert(Geno &in,char format,MultiMap *map)
221{
222if (globalobject) return globalobject->convert(in,format,map);
223if (format==in.getFormat()) return in;
224return Geno(0,0,0,"GenConvManager not initialized");
225}
226
227/////////////////////////////////
Note: See TracBrowser for help on using the repository browser.