a implementation of template class that is used for create event-driven task thread.
Diff: Actor.h
- Revision:
- 1:7d11951c1fc0
- Parent:
- 0:1f4516e81c1b
--- 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