2013年12月27日 星期五

Cross Platform NRF9160 Cortex-M33 inter thread communication

Refer to:
https://www.boost.org/doc/libs/1_60_0/doc/html/signals/tutorial.html
http://fatalfeel.blogspot.com/2013/09/how-to-program-send-message-on-corss.html

//header
class EventManager
{
public:

typedef std::vector<EventFunctorBase<EventPack>*> EventMessageSlot_Vector;
typedef std::map<int, EventMessageSlot_Vector> EventMessageSlot_Map; //<message_ID, EventPack_Vector>
static EventManager* Get();
static void Free();
EventManager();
~EventManager();
// event sinks
//void ConnectEventSlot(int messageID, EventFunctorBase<EventPack>* functor);
void ProcessEvent(int type, int messageID, void* callmember, EventPack* event);
void    ConnectEventSlot(int messageID, void* callmember);
void    DisconnectEventSlot(void* callmember);
void    SendEventMessage(EventPack* event);

private:
// event sinks
EventMessageSlot_Map m_EventMessageSlotMap;
};






//main function in cpp
void EventManager::ProcessEvent(int type, int messageID, void* callmember, EventPack* event)
{
#if defined(__ZEPHYR__)
  k_mutex_lock(&s_evtmanager_mutex, K_FOREVER);
#else
  pthread_mutex_lock(&s_evtmanager_mutex);
#endif

  unsigned int                      i;
  unsigned int                      size;
  unsigned int                      shift_p;
  unsigned int                      remain_size_vit;
  unsigned int                      remain_size_mit;
  EventMessageSlot_Vector::iterator vit;
  EventMessageSlot_Map::iterator    mit;
  EventMessageSlot_Map::iterator    tmp_ptr;
  EventFunctor<EventPack>*          functor;

  switch(type)
  {
        case EVENTMGR_CONNECT:
            functor = new EventFunctor<EventPack>((EventFunctor<EventPack>::MemberPtr)callmember);
            m_EventMessageSlotMap[messageID].push_back(functor);
            break;

        case EVENTMGR_DISCONNECT:
            mit             = m_EventMessageSlotMap.begin();
            remain_size_mit = m_EventMessageSlotMap.size();
            while(remain_size_mit > 0)
            {
              shift_p         = 0;
              remain_size_vit = mit->second.size();

              while(remain_size_vit > 0)
              {
                if( mit->second[shift_p]->GetMember() == callmember )
                {
                  vit = mit->second.begin() + shift_p;
                  delete *vit; //delete vector
                  mit->second.erase(vit);
                }
                else
                {
                  shift_p++;
                }

                remain_size_vit--;
              }

              //empty slot remove
              if( mit->second.size() <= 0 )
              {
                tmp_ptr = mit; //content copy
                mit++;
                m_EventMessageSlotMap.erase(tmp_ptr);
              }
              else
              {
                mit++;
              }

              remain_size_mit--;
            }
            break;

        case EVENTMGR_SEND:
#if !defined(__ZEPHYR__) || defined(CONFIG_DEBUG)
            printf("Start Source=%d~~~\n", event->GetSourceId());
#endif
            mit = m_EventMessageSlotMap.find(event->GetMessageId());
            if( mit != m_EventMessageSlotMap.end() ) //prevent null map
            {
              size  = mit->second.size();

              for ( i=0; i<size; i++)
                  mit->second[i]->Call(event);
            }
#if !defined(__ZEPHYR__) || defined(CONFIG_DEBUG)
            printf("End   Source=%d###\n", event->GetSourceId());
#endif
            break;
  }

#if defined(__ZEPHYR__)
  k_mutex_unlock(&s_evtmanager_mutex);
#else
  pthread_mutex_unlock(&s_evtmanager_mutex);
#endif
}



//Using method
EventPack* event = new EventPack(EVT_HEARTBEAT_FEEDBACK);
event->SetSourceId(SRC_TEST_UART00);
EventManager::Get()->SendEventMessage(event);
delete event;

source:
https://github.com/fatalfeel/nrf9160_cortexm33_itc_crossplatform

沒有留言:

張貼留言