a implementation of template class that is used for create event-driven task thread.

Committer:
mzta
Date:
Thu May 28 00:48:27 2015 +0000
Revision:
1:7d11951c1fc0
Parent:
0:1f4516e81c1b
create Actor template class.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mzta 0:1f4516e81c1b 1 #ifndef ACTOR_H
mzta 0:1f4516e81c1b 2 #define ACTOR_H
mzta 0:1f4516e81c1b 3
mzta 0:1f4516e81c1b 4 #include <map>
mzta 0:1f4516e81c1b 5 #include "mbed.h"
mzta 0:1f4516e81c1b 6 #include "rtos.h"
mzta 0:1f4516e81c1b 7
mzta 1:7d11951c1fc0 8 #define MAX_MAIL_NUM 16
mzta 1:7d11951c1fc0 9 #define STACK_SIZE 1024 * 1
mzta 0:1f4516e81c1b 10 #define START_THREAD -1
mzta 0:1f4516e81c1b 11
mzta 0:1f4516e81c1b 12 typedef uint32_t MessageID;
mzta 0:1f4516e81c1b 13
mzta 0:1f4516e81c1b 14 struct MailPacket {
mzta 1:7d11951c1fc0 15 MessageID messageId;
mzta 0:1f4516e81c1b 16 void *packet;
mzta 0:1f4516e81c1b 17 };
mzta 0:1f4516e81c1b 18
mzta 0:1f4516e81c1b 19 typedef Mail<MailPacket, MAX_MAIL_NUM> MailBox;
mzta 0:1f4516e81c1b 20
mzta 1:7d11951c1fc0 21 template <typename T>
mzta 0:1f4516e81c1b 22 class Actor
mzta 0:1f4516e81c1b 23 {
mzta 1:7d11951c1fc0 24 protected:
mzta 1:7d11951c1fc0 25 typedef void (T::*Action)(void *);
mzta 1:7d11951c1fc0 26 typedef std::map<MessageID, Action> ActionMap;
mzta 1:7d11951c1fc0 27
mzta 1:7d11951c1fc0 28 Thread thread;
mzta 1:7d11951c1fc0 29 ActionMap actions;
mzta 1:7d11951c1fc0 30 MailBox mbox;
mzta 1:7d11951c1fc0 31
mzta 0:1f4516e81c1b 32 public:
mzta 1:7d11951c1fc0 33 Actor(
mzta 1:7d11951c1fc0 34 osPriority priority = osPriorityNormal,
mzta 1:7d11951c1fc0 35 uint32_t stack_size = STACK_SIZE) :
mzta 1:7d11951c1fc0 36 thread(&Actor::threadKicker, this, priority, stack_size)
mzta 1:7d11951c1fc0 37 {
mzta 1:7d11951c1fc0 38 thread.signal_set(START_THREAD);
mzta 1:7d11951c1fc0 39 }
mzta 0:1f4516e81c1b 40
mzta 1:7d11951c1fc0 41 virtual ~Actor(){};
mzta 1:7d11951c1fc0 42
mzta 1:7d11951c1fc0 43 virtual void subscribe(MessageID msg, Action act) {
mzta 1:7d11951c1fc0 44 actions[msg] = act;
mzta 1:7d11951c1fc0 45 }
mzta 0:1f4516e81c1b 46
mzta 1:7d11951c1fc0 47 virtual void unsubscribe(MessageID msg) {
mzta 1:7d11951c1fc0 48 actions.erase(msg);
mzta 1:7d11951c1fc0 49 }
mzta 1:7d11951c1fc0 50
mzta 1:7d11951c1fc0 51 virtual void putMail(MessageID msg, void *pkt) {
mzta 1:7d11951c1fc0 52 MailPacket *mail = mbox.alloc();
mzta 1:7d11951c1fc0 53 mail->messageId = msg;
mzta 1:7d11951c1fc0 54 mail->packet = pkt;
mzta 1:7d11951c1fc0 55 mbox.put(mail);
mzta 1:7d11951c1fc0 56 }
mzta 0:1f4516e81c1b 57
mzta 0:1f4516e81c1b 58 protected:
mzta 1:7d11951c1fc0 59 virtual void threadMain() {
mzta 1:7d11951c1fc0 60 osEvent event;
mzta 1:7d11951c1fc0 61 while(true) {
mzta 1:7d11951c1fc0 62 event = mbox.get();
mzta 1:7d11951c1fc0 63 if (event.status == osEventMail) {
mzta 1:7d11951c1fc0 64 MailPacket *mail = (MailPacket*)event.value.p;
mzta 1:7d11951c1fc0 65 MessageID msg = mail->messageId;
mzta 1:7d11951c1fc0 66 void *pkt = mail->packet;
mzta 1:7d11951c1fc0 67 if (actions[msg] != NULL) {
mzta 1:7d11951c1fc0 68 (reinterpret_cast<T*>(this)->*actions[msg])(pkt);
mzta 1:7d11951c1fc0 69 }
mzta 1:7d11951c1fc0 70 mbox.free(mail);
mzta 1:7d11951c1fc0 71 }
mzta 1:7d11951c1fc0 72 }
mzta 1:7d11951c1fc0 73 }
mzta 0:1f4516e81c1b 74
mzta 1:7d11951c1fc0 75 static void threadKicker(void const *actor) {
mzta 1:7d11951c1fc0 76 Actor *instance = (Actor*)actor;
mzta 1:7d11951c1fc0 77 instance->threadMain();
mzta 1:7d11951c1fc0 78 }
mzta 0:1f4516e81c1b 79 };
mzta 0:1f4516e81c1b 80
mzta 1:7d11951c1fc0 81 template <typename T>
mzta 1:7d11951c1fc0 82 void sendMail(T *dest, MessageID msg, void *pkt) {
mzta 1:7d11951c1fc0 83 dest->putMail(msg, pkt);
mzta 1:7d11951c1fc0 84 }
mzta 1:7d11951c1fc0 85
mzta 0:1f4516e81c1b 86 #endif