// This file is a part of Framsticks SDK. http://www.framsticks.com/ // Copyright (C) 1999-2023 Maciej Komosinski and Szymon Ulatowski. // See LICENSE.txt for details. #ifndef _GENCONV_H_ #define _GENCONV_H_ #include "geno.h" #include #include #include #include #include #include class GenoConvManager; class GenoConvParam : public Param { GenoConvManager *gcm; std::vector gcnames; //stores names of converters so that these names persist and pointers to these names can be safely used externally char tmp_id[20]; //id() always returns a pointer to this array, filled with the appropriate field id. The root of the problem is that Param functions return char pointers having unspecified lifetime. In contrast, name() returns individual preallocated pointers for individual items, but apparently, id() was too simple to deserve a better but more tedious implementation. Param api will not change, but what could be improved here is perhaps using ParamObject's dynamic paramtab (which did not exist when GenoConvParam was first implemented) so we don't have to care about individual pointers at all. void freetab(); public: GenoConvParam(GenoConvManager *g); ~GenoConvParam(); void *getTarget(int); const char* id(int i); void updatetab(); }; class MultiMap; /// Base class for all Geno Converters. /// In constructor you have to set public fields indicating your identity and supported formats. /// Each converter serves one in-out format pair. /// The instance of your converter should be registered in GenoConvManager. class GenoConverter { public: const char *name; //< converter name (short) SString in_format, //< input format, e.g. "1" out_format; //< output format, e.g. "0" paInt enabled; //< don't touch this! (used by configuration module) paInt mapsupport; //< set to 1 if your converter supports genotype mapping /// You have to reimplement this method. /// If your converter cannot do its job, return empty string - return SString(); /// Any other return value is assumed to be output genotype. /// @param map if not null, mapping informaton is requested, converter should add conversion map to this object virtual SString convert(SString &i, MultiMap *map, bool using_checkpoints) = 0; /// genoconverter enable/disable fields are named "genoconv_id", where id="f"+input_format+"_f"+output_format by default. /// Converters should implement id() and provide unique value - required when adding more than one converter operating on the same formats. virtual SString id() { return SString("f") + in_format + SString("_f") + out_format; } /// Optional user-settable configuration for this converter which automatically gets added to GenoConvParam virtual ParamInterface* getParam() { return NULL; } virtual ~GenoConverter() {} /// Don't forget to set public fields in your constructor GenoConverter() :name(""), in_format(Geno::FORMAT_UNKNOWN), out_format("0"), enabled(1), mapsupport(0) {} }; /// This class gathers abilities of all converters and can convert a genotype to any other one, provided there is /// a path of GenoConverters between them. /// In most cases you don't use this class directly, Geno::getConverted(int) provides full converting functionality. /// Explicit GenoConvManager object is only needed for registering your GenoConverter. /// Use DefaultGenoConvManager to register the standard genotype converters automatically. class GenoConvManager { friend class GenoConvParam; SList converters; public: GenoConvManager(); ~GenoConvManager(); class GenoConvParam conv_enabling_param; ParamList param; /// make a genotype in other format. genotype will be invalid /// if GenoConvManager cannot convert it. Geno convert(Geno &in, SString format_list, MultiMap *map = 0, bool using_checkpoints = false, bool *converter_missing = NULL); /// register GenoConverter, the added object will be automatically deleted when GenoConvManager is destructed (call removeConverter() if this is not desirable) void addConverter(GenoConverter *conv); /// unregister GenoConverter void removeConverter(GenoConverter *conv); GenoConverter **getPath(const SString& in, const SString& out, GenoConverter **path, int maxlen, int *mapavailable = 0); /// returns the list of converters meeting the specified criteria /// pass result=0 if you only need one result (by return value) /// default criteria values mean "don't care", pass anything else to narrow your search GenoConverter *findConverters(SListTempl* result = 0, const SString& in = Geno::FORMAT_UNKNOWN, const SString& out = Geno::FORMAT_UNKNOWN, int enabled = -1, char* name = 0); }; #endif