comparison Source/Utility/Trigger.cpp @ 0:3580ffe87dc8

First commit of TouchKeys public pre-release.
author Andrew McPherson <andrewm@eecs.qmul.ac.uk>
date Mon, 11 Nov 2013 18:19:35 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:3580ffe87dc8
1 /*
2 TouchKeys: multi-touch musical keyboard control software
3 Copyright (c) 2013 Andrew McPherson
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 =====================================================================
19
20 Trigger.cpp: interface for objects to notify one another that new data
21 has arrived. TriggerSource can send triggers to any object inheriting
22 from TriggerDestination. Methods of keeping sources and destinations
23 in sync are included in each class.
24 */
25
26 #include "Trigger.h"
27
28 #undef DEBUG_TRIGGERS
29
30 void TriggerSource::sendTrigger(timestamp_type timestamp) {
31 #ifdef DEBUG_TRIGGERS
32 std::cerr << "sendTrigger (" << this << ")\n";
33 #endif
34
35 if(triggerDestinationsModified_) {
36 ScopedLock sl(triggerSourceMutex_);
37 processAddRemoveQueue();
38 }
39
40 std::set<TriggerDestination*>::iterator it = triggerDestinations_.begin();
41 TriggerDestination* target;
42 while(it != triggerDestinations_.end()) { // Advance the iterator before sending the trigger
43 target = *it; // in case the triggerReceived routine causes the object to unregister
44 #ifdef DEBUG_TRIGGERS
45 std::cerr << " --> " << target << std::endl;
46 #endif
47 target->triggerReceived(this, timestamp);
48 it++;
49 }
50 }
51
52 void TriggerSource::addTriggerDestination(TriggerDestination* dest) {
53 #ifdef DEBUG_TRIGGERS
54 std::cerr << "addTriggerDestination (" << this << "): " << dest << "\n";
55 #endif
56 if(dest == 0 || (void*)dest == (void*)this)
57 return;
58 ScopedLock sl(triggerSourceMutex_);
59 // Make sure this trigger isn't already present
60 if(triggerDestinations_.count(dest) == 0) {
61 triggersToAdd_.insert(dest);
62 triggerDestinationsModified_ = true;
63 }
64 // If the trigger is also slated to be removed, cancel that request
65 if(triggersToRemove_.count(dest) != 0)
66 triggersToRemove_.erase(dest);
67 }
68
69 void TriggerSource::removeTriggerDestination(TriggerDestination* dest) {
70 #ifdef DEBUG_TRIGGERS
71 std::cerr << "removeTriggerDestination (" << this << "): " << dest << "\n";
72 #endif
73 ScopedLock sl(triggerSourceMutex_);
74 // Check whether this trigger is actually present
75 if(triggerDestinations_.count(dest) != 0) {
76 triggersToRemove_.insert(dest);
77 triggerDestinationsModified_ = true;
78 }
79 // If the trigger is also slated to be added, cancel that request
80 if(triggersToAdd_.count(dest) != 0)
81 triggersToAdd_.erase(dest);
82 }
83
84 void TriggerSource::clearTriggerDestinations() {
85 #ifdef DEBUG_TRIGGERS
86 std::cerr << "clearTriggerDestinations (" << this << ")\n";
87 #endif
88 ScopedLock sl(triggerSourceMutex_);
89 processAddRemoveQueue();
90 std::set<TriggerDestination*>::iterator it;
91 for(it = triggerDestinations_.begin(); it != triggerDestinations_.end(); ++it)
92 (*it)->triggerSourceDeleted(this);
93 triggerDestinations_.clear();
94 }
95
96 // Process everything in the add and remove groups and transfer them
97 // into the main set of trigger destinations. Do this with mutex locked.
98 void TriggerSource::processAddRemoveQueue() {
99 #ifdef DEBUG_TRIGGERS
100 std::cerr << "processAddRemoveQueue (" << this << ")\n";
101 #endif
102 std::set<TriggerDestination*>::iterator it;
103 for(it = triggersToAdd_.begin(); it != triggersToAdd_.end(); ++it) {
104 triggerDestinations_.insert(*it);
105 #ifdef DEBUG_TRIGGERS
106 std::cerr << " --> added " << *it << std::endl;
107 #endif
108 }
109 for(it = triggersToRemove_.begin(); it != triggersToRemove_.end(); ++it) {
110 triggerDestinations_.erase(*it);
111 #ifdef DEBUG_TRIGGERS
112 std::cerr << " --> removed " << *it << std::endl;
113 #endif
114 }
115 triggersToAdd_.clear();
116 triggersToRemove_.clear();
117 triggerDestinationsModified_ = false;
118 }