Detroit engine

Siirry projektin omalle sivulle

Detroit on POSIX ympäristössä toimiva C-kielen abstraktiotaso pienten, ja miksei suurempienkin, työpöytäsovellusten tekoon. Detroit moottori tarjoaa API:n ikkunointiin, bittikarttapohjaisille widgeteille, itsenäisille grafiikkaobjekteille, äänelle, ikkunoihin liitettäville valikoille, säikeille ynnä muille UNIX systeemeistä tutuille palveluille, ja tietysti varsinaiselle DSL kielelle C-kielen abstraktointiin.

DSL kieli, Ano script, toimii siis C-kielen abstraktiona. Ano skripti tarjoaa esimerkiksi callback funktiot ikkunoiden tapahtumien käsittelyyn, sekä mekanismin liittää kätevästi C-kielisiä (ja miksei muunkin kielisiä) funktioita Ano skriptissä käytettäväksi. Ano kielisen skriptin voikin käsittää enemmän liimana erilaisten tapahtumakäsittelijöiden liittämiseksi pääohjelmaan ja datan helppoon välittämiseen tapahtumakäsittelijöiden ja muiden funktioiden välillä. C-kielellä saa nimittäin melkoista koodispagettia aikaiseksi hyvinkin helposti, ellei omiin datatyyppeihin ja niiden välittämiseen funktioiden välillä kiinnitä erityistä huomiota. Juuri tähän Ano skripti tuo osaltaan helpotusta.

Ano to C

Ano skriptiä käyttämällä on mahdollista tehdä natiivi C-kielinen ohjelma kirjoittamatta riviäkään C:tä. Ano skripti käännetään ennen varsinaisen Detroit-moottorin kääntämistä C-kielelle, joka sitten otetaan moottorin käännökseen mukaan. Näin moottorin koodi on staattista, ja Ano kääntäjän tuottama koodinpätkä on polttoainetta moottorille joka määrää mitä moottorin tulee ajoaikaisesti tehdä. Tästä sitten syntyy valmis ajettava ohjelma.

Datatyypit

Ano skriptin datatyypit käsittävät sekä C-kielestä tutut erilaiset numerotyypit (jotka ovat Anossa oletuksena double-tyyppisiä), kahvat eli handlet, merkkijonot eli stringit, sekä muutaman muun eksoottisemman datatyypin kuten koordinaattipisteen ja värin. Nämä eksoottisemmat datatyypit ovat lähinnä omaan tarkoitukseen suunniteltuja. Esimerkiksi väri-datatyyppi on hyvin kätevä apuri vaikkapa piksein piirtämisessä, perinteisestihän pikselin väri ilmoitetaan numerona, joka on jaettu RGB komponentteihin. Mutta ei Anossa. Ano skriptin datatyypissä on yksittäisten värikomponettien ohessa käyttää myös kuvaavaa värin nimeä, kuten esimerkiksi »purple», joka vastaa RGB komponenteiltaan arvoa #a020f0.

Näkyykö?

Jokainen X-Windows ikkunointisysteemin kanssa ohjelmia väkertänyt tietää miten työlästä on tehdä paljaan Xlib:n päälle edes yksinkertainen, interaktiivinen ohjelma joka hoitaa ikkunan avaamisen, siihen piirtämisen, käyttäjän touhujen palvelemisen sekä kaiken muun mitä interaktiivisen ohjelman on tehtävä ollakseen käytettävä. Xlib API:n käyttö on kuten joku viisas mies on joskus todennut, kuin selvittäisi piin arvoa roomalaisin numeroin, ja sitä se todellisuudessa melkeinpä on.

Omissa X-ikkunointia käyttävissä projekteissa en halua käyttää jo olemassa olevia käyttöliittymäkirjastoja, jotka toki tarjoaisivat ylemmän tason API:n piilottaen Xlib:n hienojakoiset ja joskus niin ohdakkeiset polut. Kaikki yleisessä käytössä olevat käyttöliittymäkirjastot ovat mielestäni joko ukonäöllisesti ja käytettävyydeltään enemmän tai vähemmän vastenmielisiä, raskaita ja paljon riippuvuuksia vaativia. Usein vieläpä näillä kirjastoilla tehdyt sovellukset tapaavat muistuttaa virastomaista lomaketta teksikenttineen ja raksittavine ruutuineen. Tähän kun vielä sekoitetaan monitasoiset, tekstiä täynnä olevat valikot on softa kuin softa luotaantyöntävyytensä takia käyttökelvoton.

Jos ajatellaan pientä C-kielistä ohjelmaa joka avaa ruudulle ikkunan, piirtää siihen yhden napin ja reagoi edes jollakin tavalla sekä ohjelman tarjoaman napin että ikkunan sulkunapin painamiseen, tulee ohjelmalle helposti pituuttaa vähintäänkin satoja rivejä. Näistä riveistä suurin osa on tietysti uudelleenkäytettävissä muissa pikku ohjelmissa, mutta kätevämpää on luoda oma käyttöliittymäkirjasto tai uudelleenkäytettävä moottori omille tarpeille.

Kuuluuko?

Jos ikkunointiin liittyvän koodin kirjoittaminen on UNIX järjestelmässä työlästä, niin sitä on totisesti myös ääniin liittyvän koodin naputtelu. Äänien käyttö ja siihen liittyvät API:t ovat BSD systeemeissä mielestäni suhteellisen fiksusti hoidettu, esimerkiksi OpenBSD tarjoaa yhden käyttöjärjestelmän laajuisen API:n äänten soittamiseen, mutta esimerkiksi Linuxista tällainen järki puuttuu. Linuxeissa äänirajapinta riippuu yleensä työpöytäympäristöstä jotka saavat itsessäni lähinnä kuvotusta aikaiseksi. Jos käyttäisin Linuxa, ei tulisi mieleenikään käyttää Gnomea tai KDE:tä tai mitä niitä työpöytäympäristöjä nyt onkaan. Mutta jos käyttäisin, pitäisi ohjelman tukea kunkin työpöytäympäristön tarjoamaa äänirajapintaa. Eli, jotta ohjelma toimisi mahdollisimman monessa työpöytäympäristössä, tulee sen tukea jo muutamaa ääni API:a, kuten PulseAudiota ja PortAudiota.

Entäs sitten ihmiset, kuten minä, jotka käyttävät pelkkää ikkunamanageria X-palvelimen päällä kiertäen työpöytäympäristöt kaukaa? No, tietysti ohjelman on toimittava myös alemman tason äänirajapintojen kanssa, Linuxissa ALSA:n ja BSD:ssä OSS:n. Äkkiä laskettuna Detroit-moottori tukee nykyisellään jo kuutta eri ääni API:a. Näihin sisältyy ALSA, OSS, OpenBSD:n sndio, ja ylemmäs mentäessä PortAudio, PulseAudio ja AO. Lisäksi olisi kai tarpeen tukea myös NAS:ia, OpenAL:aa ja ehkä vielä JACK audiota.

Jo pelkästään kuuden äänirajapinnan tukemisella voinee luottaa että ohjelma kykenee äänten soittamiseen lähes ympäristössä kuin ympäristössä, eikä kaikkien tunnettujen ja nykyään käytössä olevien rajapintojen tukemiseen liene tarvetta.

Ano-skriptin syntaksi

Ano skripti muistuttaa aika lailla assemblyä, siitä syystä että se on mielestäni luettavinta, selkeintä ja tyylikkäintä katsella. Selkeydessään se on kuin Helsingin metro, siinä ei voi mennä vikaan. Anossa on kuitenkin pikku hienouksia jota ei assystä yleensä löydy, kuten RPN tuki ja sisäänrakennetut matematiikkafunktiot.

Alla on pikku pätkä Anoa esimerkiksi, jossa lasketaan Mandelbrot kuvio ja piirretään se ruudulle piste pisteeltä. Esimerkistä kuitenkin puuttuu ikkunan avaaminen, joten se ei sellaisenaan piirrä mitään. Toimiva esimerkki löytyy täältä: http://detroit.sf.net/example_mandelbrot.html

Lisää toimiva esimerkkejä voi tutkiskella täältä: http://detroit.sf.net/static_examples.html

Vino-widgetkuvauskielen syntaksi

Vino kuvauskielen kanssa on sama perusidea kuin Ano skriptissä, helppo tapa kertoa mitä halutaan ja kääntää tuo halu C-kielelle. Detroit sisältää siis myös Vino-kääntäjän joka tuottaa C-kieltä widget-kuvauksista. Widgeteille määritellään niiden ulkonäön ja käytettävyyteen liittyvien nippelien ohella callback funktiot, jotka ovat normaaleja Ano funktioita. Callback funktioita kutsutaan aina widgetin tilan muuttuessa joko käyttäjän toimesta tai widgetin tilaa ohjelmallisesti muutettaessa.

Alla esimerkki yhden chickenhead-tyylisen pyöritettävän widgetin luomisesta Vino-kuvauskieltä käyttäen.

Menu-valikkokuvauskielen syntaksi

Mahdolliset ikkunoiden valikot määritellään yksinkertaisessa taulukossa jonka ulkonäkö vastaa ikkunan valikkorakennetta. Myös valikkotaulukko käännetään C-kielelle omalla Menu-kääntäjällä.

Alla esimerkki yksinkertaisesta valikkorakenteesta. Esimerkissä valikko on liitetty widgetiin nimeltä launcher. Valikon siis saisi hiiren valikkonappia kyseisen widgetin päällä painamalla.

~ Jani Salonen, 13.4.2017