Apua aloittajalle, onko väärin tehty, C++/CLI ja funktioiden ajo

Liittynyt
14.12.2018
Viestejä
134
Mulla on GUI:ssa kaksi nappulaa. Toisen painaminen alkaa ajamaan kahta funktiota vuorotellen ja toinen pysäyttää funktiot. Kahden funktion ajo alkaa kuitenkin tökkimään koko ohjelmaa hetken kuluttua, vähän aikaa toimii hyvin. Jos ajaa vain toista, kumpaa vain, funktiota niin ohjelma toimii vaikka mualiman tappiin. Onko mulla joku perustavanlaatuinen ajatusvirhe miten tämmöinen rakennetaan? Miten fiksummat tämmöisen tekee?

myForm.h
Koodi:
private: System::Void button17_Click(System::Object^ sender, System::EventArgs^ e) {
    stopCycle = 0;
    stop = 0;
    while (stopCycle == 0) {
        1function();
        2function();
    }
}

private: System::Void button18_Click(System::Object^ sender, System::EventArgs^ e) {
    stop = 1;
    stopCycle = 1;
}
test.cpp
Koodi:
int 1function() {

    if (stop == 0) {
        int i = 0;
        while (i < 2) {
            i++;
            //code
            }
        }
    }
    return 0;
}

int 2function() {

    if (stop == 0) {
        int i = 0;

        while (i < 6) {
            i++;
            //code
            }
        }
    } 
    return 0;
}
 
Liittynyt
31.10.2018
Viestejä
369
- Loogisesti tuossa toteutuksessa on mahdollista että 1funktion ajetaan ja 2funktion jää kokonaan ajamatta viimeisellä kierroksella kun loopit pysäyttää mutta tuo voi olla myös tarkoitettua ohjelman logiikasta riippuen.
- En ehkä itse aloittaisi funktioiden nimeä numerolla.
- Stop ja stopCycle voisi korvata yhdellä muuttujalla.
- On mahdollista painaa monta kertaa start nappia jolloin ajossa on monta looppia
- Tuosta koodista ei näe mutta Stop ja stopCycle vaikuttaisivat olevan jonkinlaisia globaaleja tai ainakin niitä säädetään ui toteutuksesta. Ehkä mieluummin kutsuisin ui toteutuksesta (painikkeen painamisesta) vain yhtä test.cpp sisältämää start tai stop funktiota joka/jotka hoitaisi kaiken logiikan. Tällöin UI ja logiikka olisi eroteltu toisistaan (vähän MVC mallin tyylisesti).

Sitten itse asiaan:
Molemmat funktiot ajetaan vuorotellen käytännössä 100% cpu kuormalla joten ohjelma voi pätkiä kun UI joutuu odottamaan vuoroaan CPU:lta
Mikäli kohdat //code sisältää jotain niin niiden sisältö saattaa vaikuttaa asiaan. Tässä oletetaan että //code on "tyhjä" kuten esimerkissä.
Loopeissa projsessori ei käytännössä tee "mitään" paitsi pyöritätä noita kahta looppia vuorotellen täydellä teholla joten iso cpu kuorma ja ohjelman "pätkiminen" voisi johtua siitä.
Nyt miksi ohjelma ei pätki kun ajossa on vain toinen looppi. Arvaan että kääntäjä saattaa olla juurikin niin fiksu että se huomaa tämän turhan suorituksen ja heivaa sen mäkeen käännösvaiheessa jolloin käännetty binäärikoodi ei sisällä tuota looppia ja cpu pääsee lepäämään.
Silloin kun koodissa on molemmat funktiot peräkkäin niin kääntäjä ei ehkä osaa arvata koodia turhaksi ja loopit jää suoritukseen tekemään lähes ei mitään.
 
Liittynyt
19.10.2016
Viestejä
5 085
Oikeat ongelmat taitaa olla paradigma tasolla. Koodi on syntaksiltaan validia (vaikkakin naiivia), mutta ilmeisesti luullaan että asioita tapahtuu automaattisesti rinnakkain vaikka todellisuudessa kirjoitetaan blokkaavaa koodia. Pysäytät käytännössä koko ohjelman ajon event callbackin sisällä. Nuo callbackit on tarkoitettu että niiden sisällä muutetaan esim UI:lla tekstikenttään teksti tai jonkin laatikon väri eriksi. Varmaan kannattaa tutustua tilakoneisiin, delegaatteihin ja WinFormssissa asyncci operaatioihin eli kuten yllä jo Prefect kertoi niin nuissa click callbackeissa kutsuttaisiin vain oman tilakoneen start() tai stop() joka tekee sitten asioita ja luo lisää eventtejä tai mitä vaan.

Ehkä jokunen perustason WinForms tutoriaali sarja ensin alle.
 
Liittynyt
14.12.2018
Viestejä
134
Noniin, sain sen toimimaan.
myForm.h kutsuu nyt vain yhtä funktiota test.cpp:ssä, joka hoitaa molemman funktion vuorottelun.

Kiitoksia vain molemmille neuvoista :)
 
Liittynyt
14.12.2018
Viestejä
134
Tohtiikohan tässä samalla kysyä vinkkiä, että miten hoitaisin jatkossa sarjaporttiviestien lähettelyn sieltä test.cpp:n puolelta? Olen tähän mennessä lähettänyt ne tuolta myForm.h:sta tällä tyylillä:
this->serialPort1 = (gcnew System::IO: ports::SerialPort(this->components));

this->serialPort1->WriteLine("viesti");

Mutta mitenhän tuota serialPort1:stä kutsutaan ulkopuolelta? Stringit saan kyllä kulkemaan filejen välillä, mutta miten sen saa tuonne serialPorttiin?
 
Viimeksi muokattu:
Liittynyt
31.10.2018
Viestejä
369
Arvaan että sinulla on käyttöliittymässä tekstikenttä lähetettävälle tekstille ja painike. Saatko tehtyä testi.cpp puolelle uuden funktion jolle parametriksi merkkijono. kun painat painiketta niin ui formin puolelta kutsut pelkästään tuota funktiota lähettäen tekstikentän sisällön kutsussa. Ehkä tekstikentän tyhjäyksen voisi hoitaa tuossa samalla ui:n puolella mutta toki olisi parempi jos se tehtäisiin vasta (vain) kun lähetys on onnistunut.
 
Liittynyt
14.12.2018
Viestejä
134
Melkein. UI:ssa on portin ja baudin valinta ja portin aukaisu. Alunperin kun form.h looppasi kahta funktiota, niin samalla hoidin sarjaporttiin viestin lähetyksen. Sarjaporttiin pitää siis lähettää aina viesti, riippuen kumpaa funktiota ajetaan. Mutta nyt kun funktiot vuorottelee kokonaan toisessa filussa, niin sieltä pitäisi jotenkin onnistua lähettämään viesti avattuun sarjaporttiin.
 
Viimeksi muokattu:
Liittynyt
19.10.2016
Viestejä
5 085
Melkein. UI:ssa on portin ja baudin valinta ja portin aukaisu. Alunperin kun form.h looppasi kahta funktiota, niin samalla hoidin sarjaporttiin viestin lähetyksen. Sarjaporttiin pitää siis lähettää aina viesti, riippuen kumpaa funktiota ajetaan. Mutta nyt kun funktiot vuorottelee kokonaan toisessa filussa, niin sieltä pitäisi jotenkin onnistua lähettämään viesti avattuun sarjaporttiin.
Mikä estää hallinnoimasta sarjaportteja samasta luokasta missä hoidat sen sinun looppauslogiikan? Olisi varmaan helpompi neuvoa kun ei tarvisi vastata ympäripyöreisiin kysymyksiin ilman että tiedetään mitä oikeasti olet edes kodestellut. Onko tämä jotain firman business logiikkaa kun ei voi asiaa avata paremmin?
 
Liittynyt
14.12.2018
Viestejä
134
Eikun omaa harrastelua, tuskin pääsisin näillä taidoilla mihinkään firmaan koodariksi :)

Homma on siis sellainen, että mulla on robotti, jossa on etu- ja takakamera. Siellä on myös kummallekin kameralle oma valaisu. Koska tämä on nyt vielä pitkään verkkovirroissa, niin sähköä ei tarvitsisi säännöstellä, mutta jos tarvitsisi, niin haluaisin oppia ja siksi haluan että vain sillä kameralla on valot päällä, joka kuvaa. Nuo funktiot, joista alunperin kerroin, on kamerankäyttöfunktioita ja siellä on kuvankäsittelyä. Windows PC lähettää Arduinolle sarjaporttiviestin, että mikä valo tarvitaan päälle. Ja nyt se viesti tarvitsisi lähteä siitä kameran funktiosta.

Mietin kyllä, että laitanko koko koodin esille, mutta koska siinä on niin paljon muitakin nappuloita ja asiaan liittymätöntä koodia, niin koitin mahdollisimman paljon yksinkertaistaa kysymystä ja hyvinhän se menikin kun heti sain toimivan neuvon alkuperäiseen kysymykseen.

Edit: Muuten varmaan voiskin hallinnoida sarjaporttia suoraan kameroiden funktioita, aukaista ja sulkea. Mutta haluaisin GUI:hin sen portin valinnan kun se voi vaihtua. Niin siksi mietin, että on luultavasti jokin tapa, miten lähettää toisesta filestä viesti jo auki olevaan sarjaporttiin. Mutta ilmeisesti tuo protected: private: System::IO: Ports::SerialPort^ serialPort1; pitäisi saada julkisemmaksi.
 
Viimeksi muokattu:
Liittynyt
31.10.2018
Viestejä
369
serial port olisi myös hyvä siirtää tuonne cpp puolelle ja pois käyttöliittymästä. Parempi olisi jos kaikki toiminnallisuus saataisiin pois käyttöliittymäkoodista ja toiminnallisuus ja datan käsittely olisi julkisten funktioiden takana.
funktioille sopivat parametrit olkoot sitten viesti merkkijonona tai sarjaportin parametrit yhteyden muodostamista varten.
Ajattele asiaa vaikka siten että voisit jossain vaiheessa haluta muokata ohjelmaa siten että sitä voisi käyttää vaikka suoraan komentoriviltä ilman gui käyttöliittymää. Gui ei siis saisi sisältää lähes mitään ohjelman kannalta olennaista logiikkaa, vaan pelkästään käyttöliittymään vaikuttavia asioita esimerkiksi jonkin painikkeen disablointi/enablointi ja mahdollinen virheen tarkistus jos käyttäjältä halutaan lukuarvo ja hän kirjoittaa merkkijonon.
Osan noista tarkistuksiatakin voisi tehdä ui koodin ulkopuolella jolloin ne olisi uudelleenkäytettävissa vaikka tuossa komentorivikäyttöliittymässä.
 
Liittynyt
27.12.2016
Viestejä
1 837
MVC on ystävä, varsinkin kun lähdetään hakemaan hajautusta.
 
Toggle Sidebar

Uusimmat viestit

Statistiikka

Viestiketjut
237 440
Viestejä
4 161 809
Jäsenet
70 409
Uusin jäsen
allun90

Hinta.fi

Ylös Bottom