source: cpp/gdk/genoconv.cpp @ 34

Last change on this file since 34 was 5, checked in by sz, 16 years ago

added the GDK (Genotype Development Kit)

File size: 4.2 KB
Line 
1// This file is a part of Framsticks GDK library.
2// Copyright (C) 2002-2006  Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.frams.alife.pl/ for further information.
4
5#include "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 "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;
34static char t[20];
35sprintf(t,"genkonw%d",i);
36return t;
37}
38
39void GenoConvParam::updatetab()
40{
41int i;
42GenoConverter *gk;
43ParamEntry *pe;
44int ile=gcm->converters.size();
45freetab();
46tab=(ParamEntry*)calloc(2+ile,sizeof(ParamEntry));
47tab[0].id="Genetics: Conversions";
48tab[0].group=1;
49tab[0].flags=ile;
50tab[0].name="gkparam:";
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        pe->name=gk->name;
57        pe->type="d 0 1";
58        pe->help=gk->info;
59        }
60pe->id=0;
61}
62
63GenoConvParam::~GenoConvParam()
64{
65freetab();
66}
67
68void *GenoConvParam::getTarget(int i)
69{
70GenoConverter *gk=(GenoConverter *)gcm->converters(i);
71return &gk->enabled;
72}
73
74GenoConvManager::GenoConvManager()
75        :param(this)
76{
77if (!globalobject) globalobject=this;
78}
79
80GenoConvManager::~GenoConvManager()
81{
82GenoConverter *gc;
83for (converters.start();gc=(GenoConverter*)converters();) delete gc;
84if (globalobject==this) globalobject=0;
85}
86
87GenoConvManager *GenoConvManager::globalobject=0;
88
89void GenoConvManager::addConverter(GenoConverter *gc)
90{
91converters+=gc;
92param.updatetab();
93}
94void GenoConvManager::removeConverter(GenoConverter *gc)
95{
96converters-=gc;
97param.updatetab();
98}
99
100/// write path into 'path'
101/// return the last path element (return >= path)
102/// null -> path not found
103/// @param mapavailable will receive 1 if conversion map is supported by all converters in path
104/// (can be NULL if you don't need this information)
105
106char *GenoConvManager::getPath(char in,char out,char *path,int maxlen,int *mapavailable)
107{
108if (!maxlen) return 0;
109GenoConverter *gk;
110int i=0;
111for (;gk=(GenoConverter*)converters(i);i++)
112        {
113        if ((gk->enabled)&&(gk->in_format == in))
114                {
115                *path=i;
116                if (gk->out_format == out)
117                        {
118                        if (mapavailable)
119                                *mapavailable=gk->mapsupport;
120                        return path;
121                        }
122                else
123                        {
124                        int mapavail;
125                        char *ret=getPath(gk->out_format,out,path+1,maxlen-1,&mapavail);
126                        if (ret)
127                                {
128                                if (mapavailable)
129                                        *mapavailable=gk->mapsupport && mapavail;
130                                return ret;
131                                }
132                        }
133                }
134        }
135return 0;
136}
137
138char *GenoConvManager::getFormatPath(char in,char out,char *path,int maxlen,int *mapavailable)
139{
140char *ret=getPath(in,out,path,maxlen,mapavailable);
141if (ret)
142        {
143        for (char*t=path;t<=ret;t++)
144                *t=((GenoConverter*)converters(*t))->out_format;
145        }
146return ret;
147}
148
149Geno GenoConvManager::convert(Geno &in,char format,MultiMap *map)
150{
151if (in.getFormat()==format) return in;
152static char path[10];
153int dep;
154char *ret;
155if (in.isInvalid()) { return Geno("",0,"","invalid genotype cannot be converted"); }
156int mapavail;
157for (dep=1;dep<sizeof(path);dep++) // sogenannte iteracyjne poglebianie...
158        if (ret=getPath(in.getFormat(),format,path,dep,&mapavail)) break;
159if (!ret) { return Geno("",0,"","converter not found"); }
160if (!map) mapavail=0;
161char *t=path;
162SString tmp;
163tmp=in.getGene();
164MultiMap lastmap,tmpmap;
165int firstmap=1;
166for (;t<=ret;t++)
167        {
168        GenoConverter *gk=(GenoConverter*)converters(*t);
169        tmp=gk->convert(tmp,mapavail?&tmpmap:0);
170        if (!tmp.len())
171                {
172                char t[100];
173                sprintf(t,"f%c->f%c conversion failed (%s)",gk->in_format,gk->out_format,gk->name);
174                return Geno(0,0,0,t);
175                }
176        if (mapavail)
177                {
178                if (firstmap)
179                        {
180                        lastmap=tmpmap;
181                        firstmap=0;
182                        }
183                else
184                        {
185                        MultiMap m;
186                        m.addCombined(lastmap,tmpmap);
187                        lastmap=m;
188                        }
189                tmpmap.clear();
190                }
191        }
192if (map)
193        *map=lastmap;
194return Geno(tmp, format, in.getName(), in.getComment());
195}
196
197Geno GenoConvManager::globalConvert(Geno &in,char format,MultiMap *map)
198{
199if (globalobject) return globalobject->convert(in,format,map);
200if (format==in.getFormat()) return in;
201return Geno(0,0,0,"GenConvManager not initialized");
202}
203
204/////////////////////////////////
Note: See TracBrowser for help on using the repository browser.