/* * Copyright (c) 2013, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following * disclaimer in the documentation and/or other materials provided with the * distribution. * * Neither the name of the Ford Motor Company nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef SRC_COMPONENTS_HMI_MESSAGE_HANDLER_INCLUDE_HMI_MESSAGE_HANDLER_HMI_MESSAGE_HANDLER_IMPL_H_ #define SRC_COMPONENTS_HMI_MESSAGE_HANDLER_INCLUDE_HMI_MESSAGE_HANDLER_HMI_MESSAGE_HANDLER_IMPL_H_ #include #include "hmi_message_handler/hmi_message_adapter.h" #include "hmi_message_handler/hmi_message_handler.h" #include "hmi_message_handler/hmi_message_handler_settings.h" #include "utils/macro.h" #include "utils/message_queue.h" #include "utils/prioritized_queue.h" #include "utils/threads/message_loop_thread.h" #include "utils/threads/thread.h" namespace hmi_message_handler { namespace impl { /* * These dummy classes are here to locally impose strong typing on different * kinds of messages * Currently there is no type difference between incoming and outgoing messages * TODO(ik): replace these with globally defined message types * when we have them. */ struct MessageFromHmi : public MessageSharedPointer { MessageFromHmi() {} explicit MessageFromHmi(const MessageSharedPointer& message) : MessageSharedPointer(message) {} // PrioritizedQueue requres this method to decide which priority to assign size_t PriorityOrder() const { return (*this)->Priority().OrderingValue(); } }; struct MessageToHmi : public MessageSharedPointer { MessageToHmi() {} explicit MessageToHmi(const MessageSharedPointer& message) : MessageSharedPointer(message) {} // PrioritizedQueue requres this method to decide which priority to assign size_t PriorityOrder() const { return (*this)->Priority().OrderingValue(); } }; typedef threads::MessageLoopThread > FromHmiQueue; typedef threads::MessageLoopThread > ToHmiQueue; } // namespace impl class ToHMIThreadImpl; class FromHMIThreadImpl; class HMIMessageHandlerImpl : public HMIMessageHandler, public impl::FromHmiQueue::Handler, public impl::ToHmiQueue::Handler { public: explicit HMIMessageHandlerImpl(const HMIMessageHandlerSettings& settings); ~HMIMessageHandlerImpl(); void OnMessageReceived(MessageSharedPointer message) OVERRIDE; void SendMessageToHMI(MessageSharedPointer message) OVERRIDE; void set_message_observer(HMIMessageObserver* observer); void OnErrorSending(MessageSharedPointer message) OVERRIDE; void AddHMIMessageAdapter(HMIMessageAdapter* adapter) OVERRIDE; void RemoveHMIMessageAdapter(HMIMessageAdapter* adapter) OVERRIDE; const HMIMessageHandlerSettings& get_settings() const OVERRIDE; #ifdef BUILD_TESTS std::set message_adapters() const { return message_adapters_; } HMIMessageObserver* observer() const { return observer_; } impl::ToHmiQueue* messages_to_hmi() { return &messages_to_hmi_; } impl::FromHmiQueue* messages_from_hmi() { return &messages_from_hmi_; } #endif // BUILD_TESTS private: // threads::MessageLoopThread<*>::Handler implementations // CALLED ON messages_from_hmi_ THREAD! void Handle(const impl::MessageFromHmi message) OVERRIDE; // CALLED ON messages_to_hmi_ THREAD! void Handle(const impl::MessageToHmi message) OVERRIDE; private: const HMIMessageHandlerSettings& settings_; HMIMessageObserver* observer_; std::set message_adapters_; mutable sync_primitives::Lock observer_locker_; mutable sync_primitives::Lock message_adapters_locker_; // Construct message threads when everything is already created // Thread that pumps messages being passed to hmi. impl::ToHmiQueue messages_to_hmi_; // Thread that pumps messages coming from hmi. impl::FromHmiQueue messages_from_hmi_; DISALLOW_COPY_AND_ASSIGN(HMIMessageHandlerImpl); }; } // namespace hmi_message_handler #endif // SRC_COMPONENTS_HMI_MESSAGE_HANDLER_INCLUDE_HMI_MESSAGE_HANDLER_HMI_MESSAGE_HANDLER_IMPL_H_