II. Könyv. rész - Gadgeteer
8. fejezet - Stopper alkalmazás készítése .NETGadgeteer-el
8.4. Az program megírása
8.4.8.4.1. Stopper osztály készítése
Készítsünk egy Stopper osztályt, az időmérésre szolgáló eszköz reprezentálásához. Az osztályt egy új kódfájlban definiáljuk. Ennek létrehozásához a jobb-egérgombbal kattintsunk a Stopper projekt ikonján, majd válasszuk ki az „Add/New Item…” opciót.
8.4. ábra - Új elem létrehozása a projektben
A megjelenő ablakban válasszuk a „Class” opciót, névnek („Name”) adjuk a következőt: „Stopper.cs”.
8.5. ábra - Új osztály hozzáadása a projekthez
Az „Add” gombra kattintva létrejön az új kódfájl a Stopper osztály definíciójával:
8.6. ábra - Az új kódfájlban elhelyezett osztálydefiníció
A stopper állapotának reprezentáláshoz szükséges egy StopperStatus nevű enum. Két állapot vehet fel az eszköz:
• Started: a stopper elindított állapotban van
Stopper alkalmazás készítése .NETGadgeteer-el
• Stopped: a stopper leállított állapotban van A forrásfájlt bővítsük az enum definícióval:
public enum StopperStatus
A stopper osztályon belül vegyük fel a következő mezőket:
public static readonly int TimerResolution = 100;
public static readonly int BufferCapacity = 3;
private Timertimer;
public TimeSpan[] LastTimes { get; private set; } private int timeIndex;
public TimeSpanMeasuredTime { get; private set; } public StopperStatus Stopperstatus { get; private set;}
public event EventHandlerStopperUpdated;
Az időmérést egy időzítő (Timer) objektum végzi, mely periódikusan, megadott időközönként (TimerResolution) növeli aMeasuredTime változót TimerResolution egységgel, illetve kiváltja a StopperUpdated eseményt. Ebből következik, hogy a mérőeszköz pontosságát is ez a változó határozza meg (jelen esetben 100 ms, azaz a mérési pontosság egytized másodperc).
Az elmentett mérési eredmények a LastTimes tömbbe kerülnek. Az eltárolt eredmények számát a BufferCapacity nevű változó segítségével lehet beállítani. Ha a bejegyzések száma elérte a maximumot, akkor körbeforgó módszerrel elölről kezdődik az indexelés, melyhez a timeIndex változó kerül felhasználásra.
A stopper indításakor, illetve leállításakor állapotátmenet következik be. Az aktuális állapotot a StopperStatus mező tárolja.
Készítsük el az inicializálást végző konstruktort:
public Stopper() {
LastTimes = new TimeSpan[BufferCapacity];
timer = new Timer(TimerResolution, Timer.BehaviorType.RunContinuously);
timer.Tick += new Timer.TickEventHandler(timer_Tick);
StopperStatus = StopperStatus.Stopped;
}
Amennyiben az időzítő Tick eseménye bekövetkezik, a timer_Tick metódus kerül meghívásra, ahol a mért időt egységnyivel növeljük, majd kiváltjuk a frissítést jelző eseményt:
void timer_Tick(Timertimer) {
A mért idő frissítését az OnStopperUpdated() metódus jelzi a StopperUpdated eseménykezelő meghívásával, ellenőrizve, hogy az eseményre történt-e feliratkozás:
private void OnStopperUpdated()
{
A stopper állapotváltását metódusok szabályozzák:
• Start(): elindítja az időmérést, illetve újraindítja azt, ha már elindult
• Stop(): leállítja az időmérést
8.7. ábra - A stopper állapotátmenet diagramja
Az egyszerűség kedvéért bevezetésre kerül egy NextState() nevű metódus is, mivel gombnyomás hatására mindig a következő állapotba kell lépni, és ez az objektum státusza alapján egyértelműen elvégezhető, így tehát nem kell „kívülről” lekérdezni az aktuális állapotot és ez alapján állapotot váltani.
A fentiek tükrében folytassuk az implementációt:
public void Start()
Stopper alkalmazás készítése .NETGadgeteer-el
private void SaveMeasuredTime() {
LastTimes[timeIndex++ % BufferCapacity] = MeasuredTime;
}
A LastTimes nevű tömb soron következő elemébe kerül beírásra az aktuálisan mért idő (MeasuredTime). A maradékos osztás biztosítja a körbeforgó indexelést.
Az idő típusú változók megjelenítéséhez szükséges azok karakterlánccá konvertálása. A .NET Micro Framework nem tartalmaz Format() metódust, és a toString() metódus sem alkalmas erre a feladatra, ezért egy sajátkészítésű Format() metódus szükséges, mely hasonló funkciót lát el:
public string Format(TimeSpan timeSpan) {
string formattedString = String.Empty;
formattedString = WithLeadingZero(timeSpan.Minutes) + ":"
+ WithLeadingZero(timeSpan.Seconds) + "."
+ timeSpan.Milliseconds / 100;
return formattedString;
}
Ez a metódus visszatérési értékként a paraméterben megadott idő perc, másodperc, és ezredmásodperc értékét szolgáltatja szöveges formában.
Mivel a megjelenítés így nem hasonlít a hagyományos stoppereknél megszokott vezető-nullás megjelenítéshez, ezért szükség van még egy segédmetódusra, amely a megadott számot string-é konvertálja, és ha szükséges vezető-nullával látja el:
private string WithLeadingZero(int number) {
A mért idő grafikus megjelenítéséhez készítsünk egy GetTimeText() nevű metódust:
public string GetTimeText() {
return Format(MeasuredTime);
}
Ezzel elkészült a Stopper osztály. A példányosított objektum szolgáltatásaita főprogramban használjuk fel.
8.4.8.4.1.8.4.1.1. A főprogram elkészítése
A Progam osztály feladata a stopper vezérlése felhasználói interakciók alapján, illetve a grafikus megjelenítés.
Az alkalmazás készítését ebben az osztályban kell folytatni (Program.cs fájl).
Definiáljuk a következő mezőket:
public static readonly GT.ColorMeasuredTimeColor = GT.Color.Red;
public static readonly GT.ColorLastTimesColor = GT.Color.White;
private Stopper stopper;
private Bitmap bitmap;
A sablon által létrehozott ProgramStarted() metódust bővítsük az alkalmazás inicializálásához szükséges hívásokkal:
Button.ButtonEventHandler(button_ButtonPressed);
bitmap = new Bitmap((int) display.Width, (int) display.Height);
UpdateUI();
}
Az stopper indítása, illetve annak megállítása az eszközhöz csatlakoztatott gomb megnyomásával történik. Az interakció kezeléséhez a button.ButtonPressed eseményre való feliratkozáskor megadott button_ButtonPressed metódus implementálása szükséges.
voidbutton_ButtonPressed(Buttonsender, Button.ButtonState state)
Amennyiben a stopper által mért idő frissül, a StopperUpdated esemény bekövetkezik és végrehajtásra kerül a stopper_Updated metódus, mely a felhasználói felület frissítését végzi:
void stopper_StopperUpdated(objectsender, EventArgs e) {
UpdateUI();
}
A frissítés során meg kell jeleníteni az aktuálisan mért időt és a rögzített időket. A rajzolás a bitmap objektum által szolgáltatott bitképre történik, majd az így elkészült kép megjelenítésre kerül a kijelzőn:
private void UpdateUI() {
string timeText = stopper.GetTimeText();
Font font =
Resources.GetFont(Resources.FontResources.NinaB);
bitmap.Clear();
bitmap.DrawText(timeText, font, MeasuredTimeColor, 0, 0);
TimeSpan[] lastTimes = stopper.LastTimes;
display.SimpleGraphics.DisplayImage(bitmap, 0, 0);
}
Stopper alkalmazás készítése .NETGadgeteer-el