Browse Source

refactor & feat: MessageStream使用Map实现

SongZihuan 3 năm trước cách đây
mục cha
commit
06b85bc00a

+ 4 - 6
include/core/env-var.h

@@ -25,16 +25,14 @@ namespace aFuncore {
 
     private:
         static const size_t ENV_VAR_HASH_SIZE = 100;  // 环境变量哈希表大小
-        struct EnvVar;
+        struct EnvVar {  // 环境变量
+            std::string str;
+            int32_t num;  // 可以同时记录字符串和数字
+        };
 
         std::unordered_map<std::string, EnvVar> var;
         std::shared_mutex lock;
     };
-
-    struct EnvVarSpace::EnvVar {  // 环境变量
-        std::string str;
-        int32_t num;  // 可以同时记录字符串和数字
-    };
 }
 
 #include "env-var.inline.h"

+ 12 - 16
include/core/msg.h

@@ -2,24 +2,17 @@
 #define AFUN_MSG_H
 #include <list>
 #include <mutex>
+#include <map>
 #include "aFuntool.h"
 #include "aFunCoreExport.h"
 
 namespace aFuncore {
     class AFUN_CORE_EXPORT Message {
-        friend class MessageStream;
-        friend class UpMessage;
-        friend class DownMessage;
-        friend class InterMessage;
-
     public:
-        const std::string type;  // 消息类型标注
-        explicit inline Message(const std::string &type_);
+        explicit inline Message() = default;
         virtual ~Message() = default;
         Message &operator=(const Message &)=delete;
 
-    private:
-        Message *next;  // 下一条消息
     };
 
     class Object;
@@ -67,33 +60,36 @@ namespace aFuncore {
 
     class AFUN_CORE_EXPORT MessageStream {
     public:
-        MessageStream();
+        MessageStream() = default;
         virtual ~MessageStream();
+        MessageStream(const MessageStream &)=delete;
         MessageStream &operator=(const MessageStream &)=delete;
 
         template<class T>
         [[nodiscard]] T *getMessage(const std::string &type) const;
 
         Message *popMessage(const std::string &type);
-        void pushMessage(Message *msg);
+        void pushMessage(const std::string &type, Message *msg);
 
         template <typename Callable, typename...T>
         void forEach(Callable func, T...arg);
 
     protected:
-        Message *stream;
+        std::map<std::string, Message *> stream;
         [[nodiscard]] virtual Message *_getMessage(const std::string &type) const;
     };
 
     class AFUN_CORE_EXPORT UpMessage : public MessageStream {
     public:
         explicit UpMessage(const UpMessage *old=nullptr);
-        ~UpMessage() override;
+        ~UpMessage() override = default;
 
-        Message *popMessage(const std::string &type);
+        template <typename Callable, typename...T>
+        void forEachAll(Callable func, T...arg);
 
     protected:
-        Message *old;
+        const UpMessage *old;
+        [[nodiscard]] Message *_getMessage(const std::string &type) const override;
     };
 
     class AFUN_CORE_EXPORT DownMessage : public MessageStream {
@@ -104,7 +100,7 @@ namespace aFuncore {
     class AFUN_CORE_EXPORT InterMessage : public MessageStream {
         std::mutex mutex;
     public:
-        Message *popFrontMessage();
+        Message *popFrontMessage(std::string &type);
     };
 }
 

+ 5 - 7
include/core/msg.inline.h

@@ -1,17 +1,15 @@
 #ifndef AFUN_MSG_INLINE_H
 #define AFUN_MSG_INLINE_H
+#include <utility>
+
 #include "msg.h"
 
 namespace aFuncore {
-    inline Message::Message(const std::string &type_) : type {type_}, next {nullptr} {
-
-    }
-
-    inline NormalMessage::NormalMessage(Object *obj_) : Message("NORMAL"), obj {obj_} {
+    inline NormalMessage::NormalMessage(Object *obj_) : obj {obj_} {
 
     }
 
-    inline NormalMessage::NormalMessage(NormalMessage &&msg) noexcept : Message("NORMAL"), obj {msg.obj}{
+    inline NormalMessage::NormalMessage(NormalMessage &&msg) noexcept : obj {msg.obj}{
         msg.obj = nullptr;
     }
 
@@ -20,7 +18,7 @@ namespace aFuncore {
     }
 
     inline ErrorMessage::ErrorMessage(ErrorMessage &&msg) noexcept
-        : Message("ERROR"), error_type{std::move(msg.error_type)}, error_info{std::move(msg.error_info)},
+        : error_type{std::move(msg.error_type)}, error_info{std::move(msg.error_info)},
           trackback{std::move(msg.trackback)}, inter{msg.inter}{
 
     }

+ 8 - 3
include/core/msg.template.h

@@ -13,9 +13,14 @@ namespace aFuncore {
 
     template <typename Callable, typename...T>
     inline void MessageStream::forEach(Callable func, T...arg) {
-        for (Message *msg = stream; msg != nullptr; msg = msg->next) {
-            func(msg, arg...);
-        }
+        for (auto &msg : stream)
+            func(msg.second, arg...);
+    }
+
+    template<typename Callable, typename... T>
+    void UpMessage::forEachAll(Callable func, T... arg) {
+        for (const UpMessage *up = this; up != nullptr; up = up->old)
+            up->MessageStream::forEach(func, arg...);
     }
 }
 

+ 3 - 3
include/core/var.template.h

@@ -5,14 +5,14 @@ namespace aFuncore {
     template <typename Callable,typename...T>
     void VarSpace::forEach(Callable func, T...arg) {
         for (int i = 0; i < VAR_HASH_SIZE; i++) {
-            for (auto tmp = var[i]; tmp != nullptr; tmp = tmp->next)
-                func(tmp, arg...);
+            for (auto &tmp : var)
+                func(tmp.second, arg...);
         }
     }
 
     template <typename Callable,typename...T>
     void VarList::forEach(Callable func, T...arg) {
-        for (auto vs : varspace)
+        for (auto &vs : varspace)
             func(vs, arg...);
     }
 }

+ 9 - 9
src/core/activation.cpp

@@ -44,7 +44,7 @@ namespace aFuncore {
         auto code_type = code->getType();
         if (code_type == Code::ByteCode::code_start) {  // start 不处理 msg
             auto *none = new Object("None", inter);
-            down.pushMessage(new NormalMessage(none));
+            down.pushMessage("NORMAL", new NormalMessage(none));
         } else {
             if (code_type == Code::ByteCode::code_element) {
                 runCodeElement(code);
@@ -79,7 +79,7 @@ namespace aFuncore {
             if (literaler != nullptr)
                 literaler->getObject(code->getElement(), code->getPrefix(), inter, *this);
             else
-                down.pushMessage(new ErrorMessage("TypeError", "Error type of literal.", this));
+                down.pushMessage("ERROR", new ErrorMessage("TypeError", "Error type of literal.", this));
         } else {
             if (varlist != nullptr)
                 obj = varlist->findObject(code->getElement());
@@ -88,9 +88,9 @@ namespace aFuncore {
                 if (cbv != nullptr && cbv->isCallBack(inter, *this))
                     cbv->callBack(inter, *this);
                 else
-                    down.pushMessage(new NormalMessage(obj));
+                    down.pushMessage("NORMAL", new NormalMessage(obj));
             } else
-                down.pushMessage(
+                down.pushMessage("ERROR",
                         new ErrorMessage("NameError", std::string("Variable ") + code->getElement() + " not fount.",
                                          this));
         }
@@ -158,11 +158,11 @@ namespace aFuncore {
                     code = call->getSon();
                     if (code == nullptr) {
                         line = 0;
-                        down.pushMessage(new ErrorMessage("SyntaxError", "Callback without code.", this));
+                        down.pushMessage("ERROR", new ErrorMessage("SyntaxError", "Callback without code.", this));
                         return as_end;
                     }
                     line = code->getFileLine();
-                    if (code->getFilePath() != "")
+                    if (!code->getFilePath().empty())
                         path = code->getFilePath();
                     return as_run;
                 case Code::ByteCode::block_b: {
@@ -187,7 +187,7 @@ namespace aFuncore {
                     }
                     if (status != func_get_func) {
                         line = 0;
-                        down.pushMessage(new ErrorMessage("SyntaxError", "Callback without code.", this));
+                        down.pushMessage("ERROR", new ErrorMessage("SyntaxError", "Callback without code.", this));
                         return as_end;
                     }
                     break;
@@ -195,7 +195,7 @@ namespace aFuncore {
                 default:
                     errorLog(aFunCoreLogger, "Error FuncActivation block type");
                     line = 0;
-                    down.pushMessage(new ErrorMessage("RuntimeError", "Error FuncActivation block type.", this));
+                    down.pushMessage("ERROR", new ErrorMessage("RuntimeError", "Error FuncActivation block type.", this));
                     return as_end;
             }
         }
@@ -210,7 +210,7 @@ namespace aFuncore {
                 func = dynamic_cast<Function *>(msg->getObject());
                 delete msg;
                 if (func == nullptr) {
-                    down.pushMessage(new ErrorMessage("TypeError", "Callback without function.", this));
+                    down.pushMessage("ERROR", new ErrorMessage("TypeError", "Callback without function.", this));
                     return as_end;
                 }
             }

+ 1 - 1
src/core/inter.cpp

@@ -86,7 +86,7 @@ namespace aFuncore {
                     break;
                 default:
                     errorLog(aFunCoreLogger, "Error activation status.");
-                    activation->getDownStream().pushMessage(
+                    activation->getDownStream().pushMessage("ERROR",
                             new ErrorMessage("RuntimeError", "Error activation status.", activation));
                     break;
             }

+ 29 - 70
src/core/msg.cpp

@@ -9,11 +9,11 @@ namespace aFuncore {
     }
 
     void NormalMessage::topProgress(Inter &inter, Activation &activation){
-        inter.getOutMessageStream().pushMessage(new NormalMessage(std::move(*this)));
+        inter.getOutMessageStream().pushMessage("NORMAL", new NormalMessage(std::move(*this)));
     }
 
     ErrorMessage::ErrorMessage(std::string error_type_, std::string error_info_, Activation *activation)
-            : Message("ERROR"), error_type{std::move(error_type_)}, error_info{std::move(error_info_)}, inter{activation->inter}{
+        : error_type{std::move(error_type_)}, error_info{std::move(error_info_)}, inter{activation->inter}{
         for (NULL; activation != nullptr; activation = activation->toPrev()) {
             if (activation->getFileLine() != 0)
                 trackback.push_front({activation->getFilePath(), activation->getFileLine()});
@@ -21,27 +21,20 @@ namespace aFuncore {
     }
 
     void ErrorMessage::topProgress(Inter &inter_, Activation &activation){
-        inter_.getOutMessageStream().pushMessage(new ErrorMessage(std::move(*this)));
-    }
-
-    MessageStream::MessageStream(){
-        stream = nullptr;
+        inter_.getOutMessageStream().pushMessage("ERROR", new ErrorMessage(std::move(*this)));
     }
 
     MessageStream::~MessageStream(){
-        for (Message *msg = stream, *tmp; msg != nullptr; msg = tmp) {
-            tmp = msg->next;
-            delete msg;
-        }
+        for (auto &msg : stream)
+            delete msg.second;
     }
 
     /**
      * 压入 Message
      * @param msg Message
      */
-    void MessageStream::pushMessage(Message *msg){
-        msg->next = stream;
-        stream = msg;
+    void MessageStream::pushMessage(const std::string &type, Message *msg){
+        stream.emplace(type, msg);
     }
 
     /**
@@ -50,11 +43,10 @@ namespace aFuncore {
      * @return Message
      */
     Message *MessageStream::_getMessage(const std::string &type) const{
-        for (Message *msg = stream; msg != nullptr; msg = msg->next) {
-            if (msg->type == type)
-                return msg;
-        }
-        return nullptr;
+        auto ret = stream.find(type);
+        if (ret == stream.end())
+            return nullptr;
+        return ret->second;
     }
 
     /**
@@ -63,74 +55,41 @@ namespace aFuncore {
      * @return Message
      */
     Message *MessageStream::popMessage(const std::string &type){
-        for (Message **msg = &stream; *msg != nullptr; msg = &((*msg)->next)) {
-            if ((*msg)->type == type) {
-                Message *ret = *msg;
-                *msg = ret->next;
-                return ret;
-            }
-        }
-        return nullptr;
+        auto ret = stream.find(type);
+        if (ret == stream.end())
+            return nullptr;
+        Message *msg = ret->second;
+        stream.erase(ret);
+        return msg;
     }
 
-    UpMessage::UpMessage(const UpMessage *old) : MessageStream(){
-        if (old != nullptr)
-            this->old = old->stream;
-        else
-            this->old = nullptr;
-        this->stream = this->old;
-    }
+    UpMessage::UpMessage(const UpMessage *old_) : MessageStream(), old{old_} {
 
-    UpMessage::~UpMessage(){
-        if (old != nullptr) {
-            for (Message **msg = &stream; *msg != nullptr; msg = &((*msg)->next)) {
-                if (*msg == old) {
-                    *msg = nullptr;
-                    break;
-                }
-            }
-        }
     }
 
-    /**
-     * 弹出Message (使Message脱离数据流)
-     * 注意: 不会弹出继承的Message
-     * @param type 类型
-     * @return Message
-     */
-    Message *UpMessage::popMessage(const std::string &type){
-        for (Message **msg = &stream; *msg != nullptr; msg = &((*msg)->next)) {
-            if ((*msg) == old)
-                break;
-            if ((*msg)->type == type) {
-                Message *ret = *msg;
-                *msg = ret->next;
+    Message *UpMessage::_getMessage(const std::string &type) const {
+        for (const UpMessage *up = this; up != nullptr; up = up->old) {
+            Message *ret = up->MessageStream::_getMessage(type);
+            if (ret != nullptr)
                 return ret;
-            }
         }
         return nullptr;
     }
 
     /**
-     * 拼接数据流
+     * 拼接数据流 (将this合并到msg)
      * @param msg
      */
     void DownMessage::joinMsg(DownMessage &msg){
-        Message *m = stream;
-        if (m == nullptr)
-            return;
-        while (m->next != nullptr)
-            m = m->next;
-        m->next = msg.stream;
-        msg.stream = m;
-        stream = nullptr;
+        msg.stream.merge(stream);
     }
 
-    Message *InterMessage::popFrontMessage() {
-        if (stream == nullptr)
+    Message *InterMessage::popFrontMessage(std::string &type) {
+        if (stream.empty())
             return nullptr;
-        Message *ret = stream;
-        stream = ret->next;
+        Message *ret = stream.begin()->second;
+        type = stream.begin()->first;
+        stream.erase(stream.begin());
         return ret;
     }
 }

+ 6 - 5
test/src/run-code.cpp

@@ -81,13 +81,13 @@ public:
     }
 };
 
-static void printMessage(Message *msg, Inter &inter) {
-    if (msg->type == "NORMAL") {
+static void printMessage(const std::string &type, Message *msg, Inter &inter) {
+    if (type == "NORMAL") {
         auto *msg_ = dynamic_cast<NormalMessage *>(msg);
         if (msg_ == nullptr)
             return;
         aFuntool::printf_stdout(0, "NORMAL: %p\n", msg_->getObject());
-    } else if (msg->type == "ERROR") {
+    } else if (type == "ERROR") {
         auto *msg_ = dynamic_cast<ErrorMessage *>(msg);
         if (msg_ == nullptr)
             return;
@@ -108,8 +108,9 @@ static void printMessage(Message *msg, Inter &inter) {
 }
 
 void printInterEvent(Inter &inter) {
-    for (auto msg = inter.getOutMessageStream().popFrontMessage(); msg != nullptr; msg = inter.getOutMessageStream().popFrontMessage()) {
-        printMessage(msg, inter);
+    std::string type;
+    for (auto msg = inter.getOutMessageStream().popFrontMessage(type); msg != nullptr; msg = inter.getOutMessageStream().popFrontMessage(type)) {
+        printMessage(type, msg, inter);
         delete msg;
     }
 }