Olen tekemässä audioplugaria, jossa on yli 20 parametria, jolla sitä voi säätää (nuppeja, slidereita, yms). Haluan päästä näihin käsiksi muuttujien avulla esim this->volume.
Parametrit pitää määritellä yhdessä paikassa, määritellä ylä- ja alarajat toisessa paikassa, alustaa jossain, tallentaa ja ladata omissa paikoissaan. Haluisin jotenkin keskitetysti määritellä kaikki parametrit yhdessä paikassa ja käydä for-loop tyylisesti läpi kaikissa näissä paikoissa, joissa kaikkia parametrejä käsitellään.
Ensimmäiseksi tuli mieleen idea, että voisin tehdä ikäänkuin macro for-loopin.
#define PARAMETERS(PARAMETER) \ PARAMETER(param1, "Parametri 1", Float, 0.0, 1.0, 0.5) \ PARAMETER(param2, "Parametri 2", Float, 0.5, 1.0, 0.7) #define DEFINE_PARAM(varName, name, type, min, max, default) type varName; PARAMETERS(DEFINE_PARAM)
Joku tuon tyylinen ratkaisu. Onko tässä mitään järkeä, onko tätä mahdollista saada toimimaan ja tuleeko parempia ideoita mieleen?
Kyllä voit tehdä noin. Muut vaihtoehdot riippuvat siitä, missä ja miten määrittelyt tarkalleen pitää tehdä. Jos parametrien nimien ja rajojen ym. määrittelyt tehdään ohjelmallisesti (funktiokutsuilla), looginen ratkaisu olisi laittaa tiedot olioihin ja käyttää ihan oikeaa for-silmukkaa. Ehkä voit myös tehdä luokan (mallin), joka sisältää parametrin nimen, arvon ja rajat ja jolle on määriteltynä sopivat sijoitus- ja muunnosoperaattorit niin, että this->volume antaa toivomasi tuloksen suoraan ja kuitenkin muut tiedot löytyvät esim. kohdista this->volume.name ja this->volume.min ja this->volume.max jne.
Koen, että malliluokkien kanssa kävisi näin:
C++ / pseudocode:
Model paramModels[] = { {"param1", Float, 0.0, 1.0}, {"param2", Bool, false, true} }; class Main { void init(); ParameterFloat param1; ParameterBool param2; } void Main::init() { for (int i = 0; i < 2; i++) { if (paramModels[i].name == "param1") param1.init(paramModels[i]); else if (paramModels[i].name == "param2") param2.init(paramModels[i]); } }
Macrojen avulla tavoitteeni oli, että parametrit tarvitsee mainita vain yhdessä paikassa eikä kolmessa. Nyt alkaa tuntua siltä, että rakennan liian vaikeaa systeemiä.
Lienee paras vaihtoehto, että kirjoitan kaikissa paikoissa kaiken koodin auki. Kun koodi toimii, voi ruveta pohtimaan, voiko koodia yksinkertaistaa. Jos kuitenkin tulee timanttinen idea vastaan, otan sen mielelläni vastaan. :)
Malli on template, ja esimerkkisi ei vastaa alkuunkaan mitään ehdotustani.
On vaikea ehdottaa tarkkaa ratkaisua, kun kysymyksestä ei käy ilmi, mitä noilla eri tiedoilla täytyy tehdä eli missä tilanteessa niitä tarvitaan. Ajattelin kuitenkin jotain tämän suuntaista:
template <typename T> struct Param { const char * const name; T value, min, max; }; class Plugin { Param<float> volume {"Volume", 1.0, 0.0, 1.0}; Param<int> foo {"Foo", 10, 0, 30}; };
Alustukset voi yleensä laittaa muodostimiin (konstruktoreihin). Tarpeistasi riippuen myös perinnästä ja virtual-sanasta saattaa joissain kohdissa olla apua.
Aihe on jo aika vanha, joten et voi enää vastata siihen.