a implementation of template class that is used for create event-driven task thread.
Actor.h
- Committer:
- mzta
- Date:
- 2015-05-28
- Revision:
- 1:7d11951c1fc0
- Parent:
- 0:1f4516e81c1b
File content as of revision 1:7d11951c1fc0:
#ifndef ACTOR_H #define ACTOR_H #include <map> #include "mbed.h" #include "rtos.h" #define MAX_MAIL_NUM 16 #define STACK_SIZE 1024 * 1 #define START_THREAD -1 typedef uint32_t MessageID; struct MailPacket { MessageID messageId; void *packet; }; typedef Mail<MailPacket, MAX_MAIL_NUM> MailBox; template <typename T> class Actor { protected: typedef void (T::*Action)(void *); typedef std::map<MessageID, Action> ActionMap; Thread thread; ActionMap actions; MailBox mbox; public: Actor( osPriority priority = osPriorityNormal, uint32_t stack_size = STACK_SIZE) : thread(&Actor::threadKicker, this, priority, stack_size) { thread.signal_set(START_THREAD); } virtual ~Actor(){}; virtual void subscribe(MessageID msg, Action act) { actions[msg] = act; } virtual void unsubscribe(MessageID msg) { actions.erase(msg); } virtual void putMail(MessageID msg, void *pkt) { MailPacket *mail = mbox.alloc(); mail->messageId = msg; mail->packet = pkt; mbox.put(mail); } protected: virtual void threadMain() { osEvent event; while(true) { event = mbox.get(); if (event.status == osEventMail) { MailPacket *mail = (MailPacket*)event.value.p; MessageID msg = mail->messageId; void *pkt = mail->packet; if (actions[msg] != NULL) { (reinterpret_cast<T*>(this)->*actions[msg])(pkt); } mbox.free(mail); } } } static void threadKicker(void const *actor) { Actor *instance = (Actor*)actor; instance->threadMain(); } }; template <typename T> void sendMail(T *dest, MessageID msg, void *pkt) { dest->putMail(msg, pkt); } #endif