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

Files at this revision

API Documentation at this revision

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
--- 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();
-}
--- 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