Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

1.Event Queue.

Ähnliche Präsentationen


Präsentation zum Thema: "1.Event Queue."—  Präsentation transkript:

1 1.Event Queue

2 Intention Das Ziel ist es den Vorgang des Sendens und des Verarbeitens voneinander zu entkoppeln

3 GUI event loops while (running) { Event event = getNextEvent();
// Handle event... }

4 GUI event loops

5 Central event bus

6 static void playSound(SoundId id, int volume);
Audio Beispiel class Audio { public: static void playSound(SoundId id, int volume); }; void Audio::playSound(Sound Id id, int volume) ResourceId resource = loadSound(id); int channel = findOpenChannel(); if (channel == -1) return; startSound(resource, channel, volume); }

7 Audio Beispiel class Menu { public: void onSelect(int index)
Audio::playSound(SOUND_BLOOP, VOL_MAX); // Other stuff... } };

8 Audio Beispiel Problem 1: Die API blockiert den 'caller' bis die Audio Engine die Request komplett verarbeitet hat Problem 2: Requests können nicht zusammen verarbeitet werden Problem 3: Requests werden im falschen Thread bearbeitet

9 Die Strukturierung Eine Queue lagert eine Serie von Meldungen oder Requests in 'first-in first-out' Reiehenfolge. Wird eine Meldung gesendet, wird die Request eingereiht. Der Request Prozessor bearbeitet die Elemente der Queue zu einem späteren Zeitpunkt. Requests können direkt bearbeitet oder an andere Einheiten weitergeleitet werden → Dies entkoppelt den Sender und Empfänger, statisch und in der Zeit.

10 When to use it? Man braucht eine Queue nur, wenn man etwas zeitlich entkoppeln will

11 Keep in mind! Event Queues sind komplex und haben weitreichende Auswirkung auf die Architektur der Anwendung → d.h. man sollte sich gut überlegen wie – und ob man sie benutzt.

12 Keep in mind! Eine zentrale Event Queue ist eine globale Variable
Der Status der Umgebung kann sich verändern Man kann in Feedback loops stecken bleiben

13 Beispiel Code struct PlayMessage { SoundId id; int volume; };

14 static const int MAX_PENDING = 16;
Beispiel Code public: static void init() { numPending_ = 0; } // Other stuff... private: static const int MAX_PENDING = 16; static PlayMessage pending_[MAX _PENDING]; static int numPending_; }; void Audio::playS ound(SoundId id, int volume) assert(numPe nding_ < MAX_PENDING) ; pending_[num Pending_].id = id; pending_[num Pending_].vo lume = volume; numPending_+ +;

15 for (int i = 0; i < numPending_ ; i++)
Beispiel Code class Audio { public: static void update() for (int i = 0; i < numPending_ ; i++) ResourceId resource = loadSound(p ending_[i]. id); int channel = findOpenCha nnel(); if (channel == -1) return; startSound( resource, channel, pending_[i] .volume); } numPending_ = 0; // Other stuff... };

16 A Ring buffer

17 class Audio { public: static void init() head_ = 0; tail_ = 0; }
A Ring buffer class Audio { public: static void init() head_ = 0; tail_ = 0; } // Methods... private: static int head_; static int tail_; // Array... };

18 A Ring buffer void Audio::playSound(SoundId id, int volume) {
assert(tail_ < MAX_PENDING); // Add to the end of the list. pending_[tail_].id = id; pending_[tail_].volume = volume; tail_++; }

19 A Ring buffer

20 A Ring buffer

21 A Ring buffer void Audio::playSound(SoundId id, int volume) {
assert((tail_ + 1) % MAX_PENDING != head_); // Add to the end of the list. pending_[tail_].id = id; pending_[tail_].volume = volume; tail_ = (tail_ + 1) % MAX_PENDING; }

22 Aggregating requests void Audio::playSound(SoundId id, int volume) {
// Walk the pending requests. for (int i = head_; i != tail_; i = (i + 1) % MAX_PENDING) if (pending_[i].id == id) // Use the larger of the two volumes. pending_[i].volume = max(volume, pending_[i].volume); // Don't need to enqueue. return; } // Previous code...

23 Design Decisions

24 Was kommt in die Queue? Events einreihen
→ Ein Event oder Benachrichtung beschreibt etwas was bereits passiert ist Meldungen einreihen → Eine Meldung oder Request beschreibt eine Aktion die in der Zukunft ausgeführt werden soll

25 Wer soll aus der Queue lesen?
Single-cast queue Broadcast queue Work queue

26 Wer soll in die Queue schreiben?
Nur ein Writer Mehrere Writer → Funktioniert mit allen read/write Konfigurationen

27 Lebenszeit eines Objektes in der Queue
Pass ownership Share ownership The Queue owns it

28 2.Service Locator

29 Intention Das Ziel eines Service Locators ist es einen globalen Zugangspunkt zu einem Service zu schaffen ohne die Benutzer mit der implementierten Klasse zu verbinden

30 Begründung // Use a static class?
AudioSystem::playSound(VERY_LOUD_BANG); // Or maybe a singleton? AudioSystem::instance()- >playSound(VERY_LOUD_BANG);

31 Keep in mind! Das Kernproblem bei einem Service Locator sind Abhängikeiten → Service Locator schaffen Flexibilität → Abhängikeiten beim Lesen des Codes schwer zu erkennen

32 Keep in mind! Service muss lokalisiert werden
Service weiß nicht von wem/was es lokalisiert wird

33 Beispiel Code Der Service class Audio { public: virtual ~Audio() {}
virtual void playSound(int soundID) = 0; virtual void stopSound(int soundID) = 0; virtual void stopAllSounds() = 0; };

34 Beispiel Code Der Service Provider class ConsoleAudio : public Audio {
virtual void playSound(int soundID) // Play sound using console audio api... } virtual void stopSound(int soundID) // Stop sound using console audio api... virtual void stopAllSounds() // Stop all sounds using console audio api... };

35 Beispiel Code Der Service Locator class Locator { public:
static Audio* getAudio() { return service_; } static void provide(Audio* service) service_ = service; } private: static Audio* service_; };;

36 Beispiel Code Registrierung des Service Provider
ConsoleAudio *audio = new ConsoleAudio(); Locator::provide(audio); Die statische Funktion getAudio() übernimmt die Lokalisierung Audio *audio = Locator::getAudio(); audio->playSound(VERY_LOUD_BANG);

37 Null service class NullAudio: public Audio { public:
virtual void playSound(int soundID) { /* Do nothing. */ } virtual void stopSound(int soundID) { /* Do nothing. */ } virtual void stopAllSounds() { /* Do nothing. */ } };

38 class LoggedAudio : public Audio
Logging Decorator class LoggedAudio : public Audio { public: LoggedAudio( Audio &wrapped) : wrapped_(wra pped) {} virtual void playSound(in t soundID) log("play sound"); wrapped_.pla ySound(sound ID); } virtual void stopSound(in t soundID) log("stop sound"); wrapped_.sto pSound(sound ID); virtual void stopAllSound s() log("stop all sounds"); wrapped_.sto pAllSounds() ;

39 Logging Decorator private: void log(const char* message) {
// Code to log message... } Audio &wrapped_; };

40 Logging Decorator void enableAudioLogging() {
// Decorate the existing service. Audio *service = new LoggedAudio(Locator::getAudio()); // Swap it in. Locator::provide(service); }


Herunterladen ppt "1.Event Queue."

Ähnliche Präsentationen


Google-Anzeigen