a implementation of template class that is used for create event-driven task thread.
Revision 1:7d11951c1fc0, committed 2015-05-28
- Comitter:
- mzta
- Date:
- Thu May 28 00:48:27 2015 +0000
- Parent:
- 0:1f4516e81c1b
- Commit message:
- create Actor template class.
Changed in this revision
Actor.cpp | Show diff for this revision Revisions of this file |
Actor.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 1f4516e81c1b -r 7d11951c1fc0 Actor.cpp --- a/Actor.cpp Wed May 20 08:11:04 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -#include "Actor.h" - -Actor::Actor() : - thread(&Actor::threadKicker, this, osPriorityNormal, STACK_SIZE) -{ - thread.signal_set(START_THREAD); -} - -Actor::~Actor() -{ -} - -void Actor::threadMain() -{ - printf("thread main\n"); - osEvent event; - while(true) { - event = mbox.get(); - if (event.status == osEventMail) { - MailPacket *mail = (MailPacket*)event.value.p; - if (joblist[mail->messageId] != NULL) { - joblist[mail->messageId](mail->packet); - } - mbox.free(mail); - } - } -} - -void Actor::subscribe(MessageID msg, void(*task)(void *)) -{ - printf("subsc\n"); - joblist[msg] = task; -} - -void Actor::unsubscribe(MessageID msg) -{ - printf("unsub\n"); - joblist.erase(msg); -} - -void Actor::sendMail(Actor *dest, MessageID msg, void *pkt) -{ - printf("sendMail\n"); - MailPacket *mail = dest->mbox.alloc(); - mail->messageId = msg; - mail->packet = pkt; - dest->mbox.put(mail); -} - -void Actor::threadKicker(void const *p) -{ - printf("thread kicker\n"); - Actor *instance = (Actor*)p; - instance->threadMain(); -}
diff -r 1f4516e81c1b -r 7d11951c1fc0 Actor.h --- a/Actor.h Wed May 20 08:11:04 2015 +0000 +++ b/Actor.h Thu May 28 00:48:27 2015 +0000 @@ -1,46 +1,86 @@ #ifndef ACTOR_H #define ACTOR_H -#include <cstdarg> #include <map> #include "mbed.h" #include "rtos.h" -#define MAX_MAIL_NUM 255 -#define STACK_SIZE 1024 * 4 +#define MAX_MAIL_NUM 16 +#define STACK_SIZE 1024 * 1 #define START_THREAD -1 -typedef void (*Routine)(void const *argument); typedef uint32_t MessageID; struct MailPacket { - uint32_t messageId; + MessageID messageId; void *packet; }; typedef Mail<MailPacket, MAX_MAIL_NUM> MailBox; -typedef std::map<MessageID, void(*)(void *)> JobList; +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(); - virtual ~Actor(); + Actor( + osPriority priority = osPriorityNormal, + uint32_t stack_size = STACK_SIZE) : + thread(&Actor::threadKicker, this, priority, stack_size) + { + thread.signal_set(START_THREAD); + } - virtual void subscribe(MessageID msg, void(*task)(void *)); + virtual ~Actor(){}; + + virtual void subscribe(MessageID msg, Action act) { + actions[msg] = act; + } - virtual void unsubscribe(MessageID msg); - - static void sendMail(Actor *dest, MessageID msg, void *pkt); + 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(); - - static void threadKicker(void const *p); + 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); + } + } + } - Thread thread; - MailBox mbox; - JobList joblist; + 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