Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Makrot ja parametrit

Touho [29.04.2018 11:13:08]

#

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?

Metabolix [29.04.2018 13:05:31]

#

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.

Touho [29.04.2018 14:17:11]

#

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. :)

Metabolix [29.04.2018 14:45:52]

#

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.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta