diff --git a/FlippR-Driver/src/input/Detector.cpp b/FlippR-Driver/src/input/Detector.cpp index 397c0dd..146221a 100644 --- a/FlippR-Driver/src/input/Detector.cpp +++ b/FlippR-Driver/src/input/Detector.cpp @@ -17,8 +17,8 @@ namespace FlippR_Driver namespace Input { -Detector::Detector(std::unique_ptr input_gpio_interface, std::map> events, std::shared_ptr event_notifier) : - input_gpio_interface(std::move(input_gpio_interface)), events(events), is_running(true), event_notifier(event_notifier) +Detector::Detector(std::unique_ptr input_gpio_interface, std::vector> events) : + input_gpio_interface(std::move(input_gpio_interface)), events(events), is_running(true) { this->detect_thread = std::thread(&Detector::detect, this); @@ -32,43 +32,20 @@ Detector::~Detector() this->detect_thread.join(); } -// Cycles over all events and enqueues an event if detected. void Detector::detect() { while(this->is_running) { - std::vector detected_addresses = check_inputs(); - for(auto& address : detected_addresses) - { - try - { - auto event = events.at(address); - CLOG(DEBUG, INPUT_LOGGER) << "Found event " << event->name << "(" << std::to_string(event->address) << ")."; - - event->distribute(); - } - catch(std::out_of_range& e) - { - CLOG_N_TIMES(1, WARNING, INPUT_LOGGER) << "Did not found event for address: " << std::to_string(address) << " check config-file"; - } - } + check_inputs(); } } -std::vector Detector::check_inputs() +void Detector::check_inputs() { - std::vector detected_addresses; - - for(char pin = 0; pin < (INPUT_MATRIX_SIZE * INPUT_MATRIX_SIZE); pin++) + for(auto& event : events) { - if(input_gpio_interface->read_data(pin)) - { - CLOG(TRACE, INPUT_LOGGER) << "Pin " << std::to_string(pin) << " is triggered."; - detected_addresses.push_back(pin); - } + input_gpio_interface->read_data(event->address) ? event->active() : event->inactive(); } - - return detected_addresses; } } diff --git a/FlippR-Driver/src/input/Detector.h b/FlippR-Driver/src/input/Detector.h index 87638e9..b2cfe40 100644 --- a/FlippR-Driver/src/input/Detector.h +++ b/FlippR-Driver/src/input/Detector.h @@ -34,19 +34,17 @@ class Detector : public IDetector { public: - Detector(std::unique_ptr input_gpio_interface, std::map> events, std::shared_ptr event_notifier); + Detector(std::unique_ptr input_gpio_interface, std::vector> events); ~Detector(); private: void detect(); - std::vector check_inputs(); + void check_inputs(); private: std::unique_ptr input_gpio_interface; - std::map> events; - - std::shared_ptr event_notifier; + std::vector> events; bool is_running; std::thread detect_thread; diff --git a/FlippR-Driver/src/input/DistributingEvent.cpp b/FlippR-Driver/src/input/DistributingEvent.cpp index 3fa26cc..67f7179 100644 --- a/FlippR-Driver/src/input/DistributingEvent.cpp +++ b/FlippR-Driver/src/input/DistributingEvent.cpp @@ -5,18 +5,47 @@ #include "DistributingEvent.h" FlippR_Driver::Input::DistributingEvent::DistributingEvent(char address, int priority, std::string name, - std::chrono::milliseconds deactivation_time, std::shared_ptr event_notifier) -: Event(address, priority, name), deactivation_time(deactivation_time), event_notifier(event_notifier) + std::chrono::milliseconds bounce_time, std::shared_ptr event_notifier) +: Event(address, priority, name), bounce_time(bounce_time), event_notifier(event_notifier) {} void FlippR_Driver::Input::DistributingEvent::distribute() { - std::chrono::time_point now = std::chrono::high_resolution_clock::now(); - std::chrono::milliseconds elapsed_time = std::chrono::duration_cast(now - last_activation); - if(elapsed_time > deactivation_time) + event_notifier->distribute_event(*this); +} + +void FlippR_Driver::Input::DistributingEvent::active() +{ + if(!is_bouncing()) { - event_notifier->distribute_event(*this); - this->last_activation = now; + if(activation_state != ACTIVATED) + { + activation_state = static_cast(static_cast(activation_state) + 1); + } + + last_activation = std::chrono::high_resolution_clock::now(); + + if(activation_state == ACTIVATED) + { + this->distribute(); + } + } +} + +bool FlippR_Driver::Input::DistributingEvent::is_bouncing() +{ + std::chrono::time_point now = std::chrono::high_resolution_clock::now(); + std::chrono::milliseconds elapsed_time = std::chrono::duration_cast(now - last_activation); + + return elapsed_time < bounce_time; +} + +void FlippR_Driver::Input::DistributingEvent::inactive() +{ + if(activation_state == 2) + { + this->last_activation = std::chrono::high_resolution_clock::now(); + activation_state = ActivationState::NOT_ACTIVATED; } } diff --git a/FlippR-Driver/src/input/DistributingEvent.h b/FlippR-Driver/src/input/DistributingEvent.h index 85e7b15..9ed30ca 100644 --- a/FlippR-Driver/src/input/DistributingEvent.h +++ b/FlippR-Driver/src/input/DistributingEvent.h @@ -16,17 +16,30 @@ class DistributingEvent : public Event { public: DistributingEvent(char address, int priority, std::string name, - std::chrono::milliseconds deactivation_time, std::shared_ptr event_notifier); + std::chrono::milliseconds bounce_time, std::shared_ptr event_notifier); + + void active(); + void inactive(); + +private: + bool is_bouncing(); void distribute(); public: - std::chrono::milliseconds deactivation_time; + std::chrono::milliseconds bounce_time; private: + enum ActivationState + { + NOT_ACTIVATED, + FIRST_ACTIVATED, + ACTIVATED + }; std::shared_ptr event_notifier; std::chrono::time_point last_activation; + ActivationState activation_state; }; }