...
- Mallinna liikennevalot UML-tilakonekaaviona esim käyttäen kaavionpiirto-ohjelmaa. Voit olettaa, että tilakoneeseen tulee tapahtuma "30 sekuntia kulunut" jolloin valoja voi vaihtaa. Voit halutessasi mallintaa myös liikennevalojen välitilat joissa keltainen valo on päällä. http://en.wikipedia.org/wiki/UML_state_machine
- Toteuta tilakoneesi tehtävästä 1 switch-case rakenteella. Voit käyttää koodin kirjoittamiseen esimerkiksi http://ideone.com/ -ympäristöä. Kieleksi voi valita esim. C++11
Esimerkki tällä tavalla toteutetusta tilakoneesta löytyy sivulta Yksinkertainen Caps Lock -tilakonemalli tai osoitteesta http://en.wikipedia.org/wiki/Event-driven_finite-state_machine - Tee Qt Creatorissa uusi käyttöliittymäsovellus. Muunna tehtävän 2 tilakone Qt-sovellukseksi.
- Kopioi C++-sovelluksesi tapahtumankäsittelijäfunktio mainwindow.cpp:hen MainWindown alaiseksi funktioksi.
- Kopioi enum-määrittelysi (tilat ja tapahtumat) mainwindow.h -tiedostoon ennen class MainWindow : public QMainWindow riviä eli varsinaisen luokkamäärittelyn ulkopuolelle
- Lisää käyttöliittymään textbrowser-ikkuna ja tulosta tilakoneen tulosteet seuraavalla addText -funktiolla cout-käskyjen sijaan. (Lisää allaoleva funktio omaan sovellukseesi, lisää funktion esittely .h -tiedostoon, ja mukauta tarvittaessa textBrowser-elementin nimi, jos olet muuttanut sitä)
void MainWindow::addText(QString text) {QString currentText=ui->textBrowser->toPlainText();
QString newText=currentText+"\n"+text;
ui->textBrowser->setText(newText);
}
- Kopioi vanhan main-funktiosi sisältö MainWindow::MainWindow(QWidget *parent) -konstruktoriin. - Lisää tilakoneeseesi QTimer-ajastin joka kutsuu ("tikkaa") tilakonetta säännöllisin väliajoin, esim. sekunnin välein. Joka ks. QTimerillä toimiva Caps Lock -esimerkki. Tapahtumia on mahdollista käsitellä joka kerralla, kun tilakone käytapahtumankäsittelijä käynnistyy, mikäli tapahtuma-jäsenmuuttujaan on asetettu tapahtuma.
QTimerin käyttö edellyttää muutoksia ohjelmaan:
- QTimer-olio lähettää signaaleja, joilla ei ole parametreja. Tämän takia tilakoneen nykyinen tila pitää välittää tapahtumankäsittelijälle toisella tapaa: Esittele tilakoneen tilaa ilmaiseva muuttuja, entisen main-funktion sijaan, mainwindow.h:ssa luokan jäsenmuuttujana. (Caps Lock -esimerkissä CapsState -tyyppinen muuttuja) Tällöin se on saatavilla kaikille luokan funktioille, ja sen arvo säilyy koko ohjelman suorituksen ajan.
- QTimer osaa kutsua vain slot-funktioita, joten lisää mainwindow.h:hon private slots: otsikko, ja siirrä tapahtumankäsittelijän esittely sinne.
- Myös tapahtumat välitetään tässä mallissa tilakoneelle jäsenmuuttujan avulla. (Caps Lock -esimerkissä Event-tyyppinen muuttuja)
- Lisää enumeraatioon, jossa mahdollisten tapahtumien valikoima on määritelty, erityinen NO_EVENT -arvo, ja tilakoneeseesi tälle tapahtumalle käsittelijä, joka ei tee mitään.
- Lisää tilakoneesi kaikkien muiden tapahtumien käsittelyihin tapahtuma-jäsenmuuttujan nollaaminen NO_EVENT -arvoon.
- Nyt voit muuttaa tilakoneen tilaa esimerkiksi ajastamalla QTimer::singleShot -funktion avulla sen kutsumaan omaa tapahtuman mukaan nimeämääsi funktiota (slotia)
QTimer::singleShot(3000,this,SLOT(keyApressed()));Joka siis täytyy lisätä mainwindow.cpp:hen (ja sen esittely mainwindow.h:hon private slots: otsikon alle):
Lisää jokaista tapahtumaasi kohti yksi tällainen tapahtumanlaukaisijafunktio, ja kutsu niitä kaikkia ajastetusti MainWindow::MainWindow-konstruktorista singleShoteina. Huomaa, että singleShot laukeaa millisekunteina sen kutsumahetkestä, eli seuraava laukaisee tapthtumanlaukaisijoita sekunneilla 3,4,5,6 ja 7 koko sovelluksen käynnistyksestä:
void MainWindow::keyApressed(){
currentEvent=KEY_A_PRESSED;
}
QTimer::singleShot(3000,this,SLOT(keyApressed()));QTimer::singleShot(4000,this,SLOT(capsLockPressed()));
QTimer::singleShot(5000,this,SLOT(keyApressed()));
QTimer::singleShot(6000,this,SLOT(capsLockPressed()));
QTimer::singleShot(7000,this,SLOT(keyApressed()));
Vaihtoehtoisesti voit toki lisätä sovellukseen jokaista tapahtumaa kohti painikkeita, joilla käyttäjä voi vapaasti laukoa tapahtumia silloin, kun haluaa. (Kytke tällöin painikkeiden clicked-signaalit omiin tapahtumanlaukaisijafunktioihisi, singleShotin käyttämisen sijaan.) - Mallinna kerrostalon hissi UML-tilakonekaaviona esim käyttäen kaavionpiirto-ohjelmaa. Sisällytä toiminnallisuuteen ainakin perustoiminnallisuus eli esim. kaikkien kerrosten painikkeet ja näytöt, jotka kertovat hissin tilasta.
- (Valinnainen lisätehtävä) Lisää tilakoneeseen myös ovien sensorit ja ajastin oven sulkeutumiselle, sekä mahdollisuus painaa useamman kerroksen painikkeita siten, että hissi muistaa mennä niihin kaikkiin yksi kerrallaan.
- Toteuta tilakone switch-case rakenteella.
Esimerkki tällä tavalla toteutetusta tilakoneesta löytyy sivulta Yksinkertainen Caps Lock -tilakonemalli tai osoitteesta http://en.wikipedia.org/wiki/Event-driven_finite-state_machine - Tee Qt Creatorissa uusi käyttöliittymäsovellus, joka simuloi hissin toimintaa.
- Toteuta aikaisemman tehtävän liikennevalot Qt:n QStateMachine:na. Esimerkki Qt:n tilakoneen käytöstä löytyy sivulta Erittäin yksinkertaiset liikennevalot Qt-tilakoneena. Kytke esimerkkiin QTimer-ajastin, joka pyörittää liikennevaloja painikkeen sijaan.
- Toteuta aikaisemman tehtävän hissi Qt:n QStateMachine:na.
- Toteuta Qt:n QStateMachinella liikennevalo-tilakone, jossa on mallinnettuna sekä yksittäisen liikennevalon, että koko risteyksen tilanne. Tarvitset tähän alitilakoneita.
...