Eseménykezelés. Aszinkron kommunikáció

Hasonló dokumentumok
Eseménykezelés. Aszinkron kommunikáció

Elemi alkalmazások fejlesztése III.

Elemi alkalmazások fejlesztése III.

Elemi alkalmazások fejlesztése III.

Eseményvezérelt alkalmazások fejlesztése I 3. előadás. Dinamikus felületű alkalmazások. Giachetta Roberto

Tervezőeszközök, fejlesztőeszközök használata Qt alapú alkalmazásoknál. Saját vezérlő használata tervezőben (worldclocks)

Elemi alkalmazások fejlesztése IV. Adatbázis-kezelő GUI alkalmazás készítése 3. Összetett tábla karbantartása

Johanyák Zsolt Csaba: Ugráló gomb oktatási segédlet Copyright 2008 Johanyák Zsolt Csaba

Budapest, március. ELTE Informatikai Kar

Elemi alkalmazások fejlesztése III.

Elemi alkalmazások fejlesztése III. A Qt assistant elindítása. Ajánlott ir odalom. A Qt assistant nyitó ablaka

Alkalmazások fejlesztése III. Qt 4 /C++ alapú grafikus alkalmazás Bevezetés I.

Elemi alkalmazások fejlesztése III

Egységes és objektumközpontú adatbázis-kezelés (2. rész)

Programozás II. ATM példa Dr. Iványi Péter

Dinamikus felületű alkalmazások. Stílusok, időzítő, képek

Concurrency in Swing

QLabel *label = new Qlabel("Hello Qt!",0);

Grafikus Qt programok írása segédeszközök nélkül

BME MOGI Gépészeti informatika 7.

Programozás II gyakorlat. 4. Öröklődés

Programozás BMEKOKAA146. Dr. Bécsi Tamás 8. előadás

ESEMÉNY VEZÉRELT ALKALMAZÁSOK FEJLESZTÉSE I. Bevezetés. Készítette: Gregorics Tibor

Hálózati alkalmazások

Elemi alkalmazások fejlesztése IV.

MySql elindítása. Elemi alkalmazások fejlesztése IV. Feladat. Az alkalmazás adatbázisa

Ugráló gomb oktatási segédlet Ugráló gomb

Informatika terméktervezőknek

Számítástechnika II. BMEKOKAA Előadás. Dr. Bécsi Tamás

Vizuális és eseményvezérelt programozás , II. félév BMF NIK

BME MOGI Gépészeti informatika 4.

Elemi alkalmazások fejlesztése III

C# nyelv alapjai. Krizsán Zoltán 1. Objektumorientált programozás C# alapokon tananyag. Általános Informatikai Tanszék Miskolci Egyetem

Adabáziselérés ODBC-n keresztül utasításokkal C#-ban

osztályok kapcsolata Származtatatás C++ Izsó Tamás március 19. Izsó Tamás Származtatatás/ 1

components : IContainer dx : int dy : int tmidőzítő : Timer toolstripseparator1 : ToolStripSeparator tsmikilépés : ToolStripMenuItem

Access adatbázis elérése OLE DB-n keresztül

Form1 Form Size 400;400 Text Mozgó kör timer1 Timer Enabled True Interval 100

Eseményvezérelt alkalmazások fejlesztése II 5. előadás. Windows Forms alkalmazások párhuzamosítása. Giachetta Roberto

Tervminták a valósidejű gyakorlatban

Konkurens TCP Szerver

3D-s számítógépes geometria és alakzatrekonstrukció

Johanyák Zsolt Csaba: Grafikus felület programozása. Copyright 2008 Johanyák Zsolt Csaba

OAF Gregorics Tibor: Minta dokumentáció a 3. házi feladathoz 1.

Objektum elvű alkalmazások fejlesztése Kifejezés lengyel formára hozása és kiértékelése

A C# programozási nyelv alapjai

Elemi alkalmazások fejlesztése III.

2. Beadandó feladat dokumentáció

A Microsoft Visual Studio 2005 fejlesztőkörnyezet

Qt rajzolás munkafüzet. Elemi Alkalmazások fejlesztése 3.

2. Beadandó feladat dokumentáció

Java és web programozás

Szoftvertechnológia alapjai Java előadások

Sorosítás (szerializáció) és helyreállítás. 1. Bináris sorosítás és helyreállítás Szükséges névterek Attribútumok. 1.3.

Eseménykezelés - Lottó játék

Pál László. Sapientia EMTE, Csíkszereda, 2014/2015

Segítség a megoldáshoz: 1. Készítse el a Window-t az ábrának és az osztálydiagramnak megfelelően.

Programozás C nyelven (3. ELŐADÁS) Sapientia EMTE

EAF II Feladat dokumentáció IV. feladat 4. házi feladathoz

Elemi alkalmazások fejlesztése III.

Programozás BMEKOKAA146. Dr. Bécsi Tamás 1. Előadás

main int main(int argc, char* argv[]) { return 0; } main return 0; (int argc, char* argv[]) main int int int main main main

Objektumorientált programozás C# nyelven III.

1000.AA Megoldo Alfréd 1000.A

BME MOGI Gépészeti informatika 6.

Osztályok. 4. gyakorlat

1.AA MEGOLDÓ BERCI AA 1.

// keressük meg a legnagyobb faktoriális értéket, ami kisebb, // mint százmillió

BME MOGI Gépészeti informatika 1.

Alkalmazások fejlesztése III. Qt 4 /C++ alapú MDI alkalmazás: Számlakészítő program 3/3

3. Osztályok II. Programozás II

Programozás C nyelven FELÜLNÉZETBŐL elhullatott MORZSÁK. Sapientia EMTE

1. Template (sablon) 1.1. Függvénysablon Függvénysablon példányosítás Osztálysablon

C#, OOP. Osztályok tervezése C#-ban

Alprogramok, paraméterátadás

Elemi alkalmazások fejlesztése III

Kölcsönös kizárás, atomicitás, szemafor.

Eseményvezérelt alkalmazások fejlesztése II 5. előadás. Windows Forms alkalmazások párhuzamosítása. Cserép Máté

Számítástechnika I. BMEKOKAA152 BMEKOKAA119 Infokommunikáció I. BMEKOKAA606. Dr. Bécsi Tamás

bool _freehand = false; QPoint _lastpoint; // ebben a pontban volt az utolsó rajzolásnál az egérmutató

Java Programozás 1. Gy: Java alapok. Ismétlés ++

Elemi Alkalmazások Fejlesztése Beadandó Feladat Juhász Ádám

Objektum elvű alkalmazások fejlesztése Programozási tételek újrafelhasználása 1. Készítette: Gregorics Tibor

117. AA Megoldó Alfréd AA 117.

1. Alapok. Programozás II

CAN alapú járműves adatokat megjelenítő szoftver fejlesztése

A lista eleme. mutató rész. adat rész. Listaelem létrehozása. Node Deklarálás. Létrehozás. Az elemet nekünk kell bef zni a listába

Java VI. Egy kis kitérő: az UML. Osztály diagram. Általános Informatikai Tanszék Utolsó módosítás:

3. Beadandó feladat dokumentáció

Felhasználó által definiált adattípus

Események C#-ban Krizsán Zoltán iit

Kivételkezelés a C++ nyelvben Bevezetés

Programozás(A szakirány) II. beadandó feladat Farkas András HP6S15 1. csoport Veszprémi Anna / Hudoba Péter

Mérési adatgyűjtés és adatfeldolgozás 2. előadás

abkezel.java import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.sql.*; public class abkezel extends JFrame {

Objektumorientált programozás C# nyelven

Modellező eszközök, kódgenerálás

INFORMATIKAI ALAPISMERETEK

Matlab alapok. Baran Ágnes. Baran Ágnes Matlab alapok Elágazások, függvények 1 / 15

Átírás:

Eseménykezelés Aszinkron kommunikáció

Feladat Készítsünk egy stoppert, amely másodpercenként jelzi a múló időt. Ez a folyamat egy adott jelzés hatására induljon el; ugyanezen jelzés ismétléseinek hatására váltakozva szüneteljen illetve folytatódjon tovább; egy adott másik jelzés hatására álljon le. 2

Használati eset diagram: elemzés inicializálja az alkalmazást <<invoke>> idő kijelző nulla másodpercet mutat elindítja a stoppert <<invoke>> idő kijelző értéke másodpercenként eggyel nő user megállítja a stoppert <<invoke>> idő kijelző nem változik kilép a programból 3

Együttműködési diagram: elemzés click quit :Stopper start() stop() tick :Timer display(seconds) :LcdNumber 4

Osztálydiagram: elemzés Stopper Timer - seconds : int + start() + stop() «enumeration» Signal tick click quit LcdNumber + display(int) 5

Szekvencia diagram: elemzés :Stopper :Timer :LcdNumber start() loop tick [ per seconds] loop click loop tick [ per seconds] display() click loop tick [ per seconds] quit stop() 6

Stopper állapot-átmenet diagramja / seconds := 0 / lcd.display(seconds) / timer.start() tick stopped click click tick / lcd.display(++seconds) operate quit / timer.stop() quit / timer.stop() 7

Osztálydiagram: tervezés Stopper - seconds : int - currentstate : State - processevent(signal) : void Timer - active : bool + start() + stop() «enumeration» State operate stopped «enumeration» Signal tick click quit LcdNumber + display(int) 8

Stopper állapot-átmenet kódja processevent(event:signal) : void switch (currentstate) case stopped: switch (event) case click: currentstate = operate; case tick: ; case quit: exit; case operate: switch (event) case click: currentstate = stopped; case tick: lcd.display(++seconds); case quit: exit; «enumeration» Signal tick click quit «enumeration» State operate stopped 9

Megvalósítás Többszálú alkalmazásra van szükség, mert több aktív objektum van jelen, amelyek a stopper állapotgépének aszinkron módon üzennek. Külön szálon kell futnia a stopper állapotgépének, valamint a timer órajelet küldő metódusának. Az egyes szálak aktivitásának jelzésére olyan logikai változókra lesz szükség, amelyet több szál egymást kizárva képes használni. A fogadó objektum a több irányból érkező aszinkron üzeneteket egy eseménysorba gyűjti. Az eseménysorba a fogadó objektum által biztosított send() metódus szinkron hívása által kerülnek be események a fogadó objektum állapotgépétől eltérő szálakon. Az eseménysorból a fogadó objektum állapotgépe veszi ki az eseményeket. Az eseménysor műveleteinek kölcsönösen kizárásos módon kell működnie, és üres sor esetén a kivétel műveletét blokkolni kell. 10

Együttműködési diagram: megvalósítás :ThreadSafeQueue send(click) send(quit) enqueue() dequeue() :Stopper start() stop() send(tick) :Timer display(seconds) Az aszinkron hívást a :Stopper állapotgépétől eltérő szálakon kezdeményezett szinkron hívás helyettesíti. :LcdNumber 11

Osztálydiagram: megvalósítás Stopper - seconds : int - currentstate : State - active : bool + send(e : Signal):void - processevent(signal) : void - statemachine() : void «enumeration» State operate stopped «enumeration» Signal tick click quit eventqueue.enqueue(e) - timer - display while (active) do eventqueue.dequeue(e); processevent(e); od Signal - eventqueue Timer - active : bool + start() + stop() - statemachine() : void + display(int) LcdNumber ThreadSafeQueue + enqueue(t) + dequeue(t) T 12

Stopper osztály class Stopper enum Signal tick, click, quit; public: Stopper(); ~Stopper(); void send(signal event) _eventqueue.enqueue(event); private: enum State operate, stopped; void statemachine(); void processevent(signal event); State _currentstate; int _seconds; bool _active; std::thread _processorthread; külön szál a Stopper::stateMachine()-nek #include <thread> ; Timer _timer; LcdNumber _lcd; ThreadSafeQueue<Signal> _eventqueue; stopper.h 13

Stopper osztály Stopper::Stopper() : _currentstate(stopped),_seconds(0), _processorthread(&stopper::statemachine, this) _lcd.display(_seconds); _eventqueue.startqueue(); _timer.start(); Külön szálon indul el a Stopper állapotgépe. void Stopper::stateMachine() _active = true; while(_active) //amíg nincs terminálás Signal event; _eventqueue.dequeue(event); if(_active) processevent(event); Stopper::~Stopper() _processorthread.join(); _timer.stop(); _eventqueue.stopqueue(); Bevárja amíg az állapotgép leáll. stopper.cpp 14

Stopper eseménykezelője void Stopper::processEvent(Signal event) switch (_currentstate) // mi az állapot case stopped: switch (event) // mi az esemény case click: _currentstate = operate; break; case tick : break; case quit : _active = false; break; break; case operate: switch (event) // mi az esemény case click: _currentstate = stopped; break; case tick : _lcd.display(++_seconds); break; case quit : _active = false; break; break; stopper.cpp 15

Timer osztály class Stopper; class Timer typedef std::chrono::milliseconds milliseconds; public: Timer(Stopper *t) : _target(t), _active() _active = false; void start() ; void stop() ; private: void statemachine(); ; Stopper *_target; std::atomic_bool _active; std::thread _processorthread; szálbiztos logikai változó, amit több szál is használ #include <atomic> külön szál a Timer::stateMachine()-nek #include <thread> timer.h 16

Timer osztály void Timer::start() _active = true; _processorthread = new std::thread(&timer::statemachine, this); void Timer::stop() _active = false; _processorthread->join(); void Timer::stateMachine() std::condition_variable _cond; while (_active) std::mutex mu; std::unique_lock<std::mutex> lock(mu); _cond.wait_for(lock, milliseconds(1000)); _target->send(tick); Külön szálon indul el a Timer állapotgépe. speciális változó a várakozás megvalósításához #include <condition_variable> szemafor #include <mutex> Egy másodpercig blokkolja a szálat. timer.cpp 17

ThreadSafeQueue osztálysablon template <typename T> class ThreadSafeQueue public: ThreadSafeQueue() _active = false; void enqueue(const T& e) ; void dequeue(t& e) ; A _cond objektummal blokkolt összes szálnak engedélyezi a folytatást. void startqueue() _active = true; void stopqueue() _active = false; _cond.notify_all(); bool empty() const return _queue.empty(); private: std::queue<t> _queue; ; std::atomic_bool _active; std::mutex _mu; std::condition_variable _cond; threadsafequeue.hpp 18

ThreadSafeQueue osztálysablon template <typename T> void ThreadSafeQueue::enqueue(const T& e) std::unique_lock<std::mutex> lock(_mu); _queue.push(e); _cond.notify_one(); void ThreadSafeQueue::dequeue(T& e) std::unique_lock<std::mutex> lock(_mu); while(empty() && _active) _cond.wait(lock); if(_active) e = _queue.front(); _queue.pop(); threadsafequeue.hpp 19

LcdNumber osztály class LcdNumber public: void display(int seconds) int hours = seconds / 3600; int minutes = (seconds % 3600) / 60; std::string time = convertvalue(hours) + ":" + convertvalue(minutes) + ":" + convertvalue(((seconds % 3600) % 60)); std::cout << time << std::endl; private: std::string convertvalue(int val) return val<10? "0"+std::to_string(val) : std::to_string(val); ; lcdnumber.h 20

main() függvény int main() Stopper stopper; std::cout << "Choise option:" << std::endl; char o; do std::cin >> o; if(o == 's') stopper.send(click); while(o!= 'q'); stopper.send(quit); return 0; main.cpp 21

Stopper Qt-val fejlesztve QWidget Egyszerre ablak és olyan objektum, amely vezérlőket (timer, textbox, button) tárol, és támogatja az ezek közötti aszinkron üzenetek kezelését. QLCDNumber QPushButton #include <QApplication> QApplication #include "stopper.h" Többek között gondoskodik arról, hogy az int main(int argc, char *argv[]) események a megfelelő vezérlőhöz eljutva QApplication app(argc,argv); szignálként jelenjenek meg. Stopper *stopper = new Stopper; stopper->show(); return app.exec(); main.cpp 22

Stopper osztály, mint QWidget #include <QWidget> class QTimer; class QLCDNumber; class QPushButton; enum State stopped, operate; class Stopper: public Qwidget Q_OBJECT public: Stopper(QWidget *parent=0); protected: void closeevent(qcloseevent * event) stop() ; private: QTimer *_timer; A kilépés (quit) eseményéhez QLCDNumber *_lcd; rendeli a stop() eseménykezelőt, QPushButton *_button; amelyik a timer-t leállítja. State _currentstate; ; int _seconds; private slots: void onesecondpass(); // tick void buttonpressed(); // click void stop(); // quit több eseménykezelő függvény a processevent() helyett stopper.h 23

Stopper osztály Qt eseménykezelése Stopper::Stopper(QWidget *parent) : Qwidget(parent) setwindowtitle(tr("stopper")); resize(150, 60); _timer = new QTimer; _lcd = new QLCDNumber; _button = new QPushButton("Start/Stop"); connect(_timer, SIGNAL(timeout()), this, SLOT(oneSecondPass())); connect(_button, SIGNAL(clicked()), this, SLOT(buttonPressed())); _currentstate = stopped; _seconds = 0; _lcd->display(_seconds); _timer->start(1000); vezérlők elrendezésének és egyéb tulajdonságainak megadása események és kezelésük egymáshoz rendelése: tick ~ timeout() click ~ clicked() stopper.cpp 24

Stopper osztály Qt eseménykezelői Stopper::oneSecondPass() ez a kód a proccesevent() egyik részlete switch (_currentstate) case operate: _lcd->display(++_seconds); break; case stopped: break; Stopper::buttonPressed() ez a kód a proccesevent() másik részlete switch (_currentstate) case operate: _currentstate = stopped; break; case stopped: _currentstate = operate; break; Stopper::stop() _timer->stop(); stopper.cpp 25

Stopper.net alatt fejlesztve Form Ablak és objektum egyben, amely vezérlőket (timer, textbox, button) tárol, és támogatja az ezek közötti aszinkron üzenetek kezelését. TextBox Button static class Program [STAThread] static void Main() Application.EnableVisualStyles(); Application Többek között gondoskodik arról, hogy az események a megfelelő vezérlőhöz eljutva szignálként jelenjenek meg. Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Stopper()); program.cs 26

Stopper osztály, mint.net Form public partial class Stopper : Form enum State stopped, operate ; State _currentstate; DateTime _seconds = new DateTime(0); private System.Windows.Forms.Timer _timer; private System.Windows.Forms.Button _button; private System.Windows.Forms.TextBox _lcd; public Stopper() this.components = new System.ComponentModel.Container(); this.button = new System.Windows.Forms.Button(); this.lcd = new System.Windows.Forms.TextBox(); this.timer = new System.Windows.Forms.Timer(this.components); this.text = "Stopper"; this.button.text = "Start/Stop"; this.lcd.text = "00:00"; this.timer.interval = 1000; this.controls.add(this.lcd); this.controls.add(this.button); vezérlők elrendezésének és egyéb tulajdonságainak megadása Stopper.cs 27

Stopper osztály.net eseménykezelése események és kezelésük egymáshoz rendelése this._timer.tick += new System.EventHandler(oneSecondPass); this._button.click += new System.EventHandler(buttonPressed); this.formclosed += new System.Windows.Forms. FormClosedEventHandler(stop); _currentstate = State.stopped; display(); _timer.start(); quit FormedClosed private void onesecondpass(object sender, EventArgs e) private void buttonpressed(object sender, EventArgs e) private void stop(object sender,formclosedeventargs e)_timer.stop(); private void display() a tervvel ellentétben ez nem az lcd kijelző, hanem a _lcd.text = string.format("0:1", stopper metódusa seconds.minute.tostring().padleft(2, '0'), seconds.second.tostring().padleft(2, '0')); Stopper.Designer.cs 28