Sfoglia il codice sorgente

feat: 添加TopMsgProcess模块

SongZihuan 3 anni fa
parent
commit
55a0e7b4de
5 ha cambiato i file con 143 aggiunte e 7 eliminazioni
  1. 11 1
      include/env.h
  2. 10 1
      src/core/__env.h
  3. 95 4
      src/core/env.c
  4. 16 0
      src/main.c
  5. 11 1
      test/test_dlc.c

+ 11 - 1
include/env.h

@@ -1,9 +1,14 @@
 #ifndef AFUN__ENV_H_PUBLIC
 #define AFUN__ENV_H_PUBLIC
+#include "macro.h"
+#include "tool.h"
 
 typedef struct af_Environment af_Environment;
 typedef struct af_Message af_Message;
 
+typedef void TopMsgProcessFunc(af_Message *msg, af_Environment *env);
+NEW_DLC_SYMBOL(TopMsgProcessFunc, TopMsgProcessFunc);
+
 #include "code.h"
 #include "object.h"
 #include "var.h"
@@ -21,7 +26,8 @@ af_Message *freeMessage(af_Message *msg);
 void freeAllMessage(af_Message *msg);
 void pushMessageUp(af_Message *msg, af_Environment *env);
 void pushMessageDown(af_Message *msg, af_Environment *env);
-void *popMessageUp(char *type, af_Environment *env);
+void *popMessageUpData(char *type, af_Environment *env);
+af_Message *popMessageUp(af_Environment *env);
 void *getMessageData(af_Message *msg);
 af_Message *popMessageDown(char *type, af_Environment *env);
 af_Message *getFirstMessage(af_Environment *env);
@@ -30,4 +36,8 @@ void connectMessage(af_Message **base, af_Message *msg);
 void setEnvVar(char *name, char *data, af_Environment *env);
 char *findEnvVar(char *name, af_Environment *env);
 
+void addTopMsgProcess(char *type, DLC_SYMBOL(TopMsgProcessFunc) func,
+                      af_Environment *env);
+bool changeTopMsgProcess(char *type, DLC_SYMBOL(TopMsgProcessFunc) func,
+                         af_Environment *env);
 #endif //AFUN__ENV_H_PUBLIC

+ 10 - 1
src/core/__env.h

@@ -1,11 +1,13 @@
 #ifndef AFUN__ENV_H
 #define AFUN__ENV_H
 #include "macro.h"
+#include "tool.h"
 
 typedef struct af_Core af_Core;
 typedef struct af_Activity af_Activity;
 typedef struct af_EnvVarSpace af_EnvVarSpace;
 typedef struct af_EnvVar af_EnvVar;
+typedef struct af_TopMsgProcess af_TopMsgProcess;
 
 #include "env.h"
 #include "__object.h"
@@ -67,6 +69,12 @@ struct af_Activity {  // 活动记录器
     struct af_Message *return_msg;  // 调用者向被调用者传递信息
 };
 
+struct af_TopMsgProcess {  // 顶层msg处理器
+    char *type;
+    DLC_SYMBOL(TopMsgProcessFunc) func;  // 在 env.h 中定义
+    struct af_TopMsgProcess *next;
+};
+
 struct af_EnvVar {  // 环境变量
     char *name;
     char *data;
@@ -79,8 +87,9 @@ struct af_EnvVarSpace {  // 环境变量
 
 struct af_Environment {  // 运行环境
     struct af_Core *core;
-    struct af_Activity *activity;
     struct af_EnvVarSpace *esv;
+    struct af_Activity *activity;
+    struct af_TopMsgProcess *process;
 };
 
 af_Object *getBaseObjectFromCore(char *name, af_Core *core);

+ 95 - 4
src/core/env.c

@@ -16,6 +16,12 @@ static af_EnvVar *freeEnvVar(af_EnvVar *var);
 static void freeAllEnvVar(af_EnvVar *var);
 static void freeEnvVarSpace(af_EnvVarSpace *evs);
 
+static af_TopMsgProcess *makeTopMsgProcess(char *type, DLC_SYMBOL(TopMsgProcessFunc) func);
+static af_TopMsgProcess *freeTopMsgProcess(af_TopMsgProcess *mp);
+static void freeAllTopMsgProcess(af_TopMsgProcess *mp);
+static void *findTopMsgProcessFunc(char *type, af_Environment *env);
+static void runTopMessageProcess(af_Environment *env);
+
 static af_Core *makeCore(void) {
     af_Core *core = calloc(sizeof(af_Core), 1);
     core->in_init = true;
@@ -216,7 +222,7 @@ void pushMessageDown(af_Message *msg, af_Environment *env) {
     env->activity->msg_down = msg;
 }
 
-void *popMessageUp(char *type, af_Environment *env) {
+void *popMessageUpData(char *type, af_Environment *env) {
     for (af_Message **pmsg = &env->activity->msg_up; *pmsg != NULL; pmsg = &((*pmsg)->next)) {
         if (EQ_STR((*pmsg)->type, type))
             return (*pmsg)->msg;  // msg_up是只读的
@@ -224,6 +230,17 @@ void *popMessageUp(char *type, af_Environment *env) {
     return NULL;
 }
 
+af_Message *popMessageUp(af_Environment *env) {
+    if (env->activity->new_vs_count == 0 || env->activity->msg_up == NULL)
+        return NULL;
+
+    af_Message *msg = env->activity->msg_up;
+    env->activity->msg_up = msg->next;
+    msg->next = NULL;
+    env->activity->new_vs_count--;
+    return msg;
+}
+
 /*
  * 函数名: getMessageData
  * 目标: 获取`msg`的数据, 对外API
@@ -315,10 +332,22 @@ char *findEnvVar(char *name, af_Environment *env) {
     return NULL;
 }
 
+void mp_NORMAL(af_Message *msg, af_Environment *env) {
+    if (msg->msg == NULL || *(af_Object **)msg->msg == NULL) {
+        printf("msg: %p error\n", msg->msg);
+        return;
+    }
+    gc_delReference(*(af_Object **)msg->msg);
+    printf("NORMAL Point: %p\n", *(af_Object **)msg->msg);
+}
+
 af_Environment *makeEnvironment(void) {
     af_Environment *env = calloc(sizeof(af_Environment), 1);
+    DLC_SYMBOL(TopMsgProcessFunc) func = MAKE_SYMBOL(mp_NORMAL, TopMsgProcessFunc);
     env->core = makeCore();
     env->esv = makeEnvVarSpace();
+    addTopMsgProcess("NORMAL", func, env);
+    FREE_SYMBOL(func);
     return env;
 }
 
@@ -342,6 +371,7 @@ void freeEnvironment(af_Environment *env) {
     freeCore(env->core);
     freeAllActivity(env->activity);
     freeEnvVarSpace(env->esv);
+    freeAllTopMsgProcess(env->process);
     free(env);
 }
 
@@ -349,6 +379,52 @@ bool addVarToProtectVarSpace(af_Var *var, af_Environment *env) {
     return addVarToVarSpace(var, env->core->protect);
 }
 
+static af_TopMsgProcess *makeTopMsgProcess(char *type, DLC_SYMBOL(TopMsgProcessFunc) func) {
+    af_TopMsgProcess *mp = calloc(sizeof(af_TopMsgProcess), 1);
+    mp->type = strCopy(type);
+    mp->func = COPY_SYMBOL(func, TopMsgProcessFunc);
+    return mp;
+}
+
+static af_TopMsgProcess *freeTopMsgProcess(af_TopMsgProcess *mp) {
+    af_TopMsgProcess *next = mp->next;
+    free(mp->type);
+    FREE_SYMBOL(mp->func);
+    free(mp);
+    return next;
+}
+
+static void freeAllTopMsgProcess(af_TopMsgProcess *mp) {
+    while (mp != NULL)
+        mp = freeTopMsgProcess(mp);
+}
+
+static void *findTopMsgProcessFunc(char *type, af_Environment *env) {
+    af_TopMsgProcess *mp = env->process;
+    for (NULL; mp != NULL; mp = mp->next) {
+        if (EQ_STR(type, mp->type))
+            return mp;
+    }
+    return NULL;
+}
+
+void addTopMsgProcess(char *type, DLC_SYMBOL(TopMsgProcessFunc) func,
+                      af_Environment *env) {
+    af_TopMsgProcess *mp = makeTopMsgProcess(type, func);
+    mp->next = env->process;
+    env->process = mp;
+}
+
+bool changeTopMsgProcess(char *type, DLC_SYMBOL(TopMsgProcessFunc) func,
+                         af_Environment *env) {
+    af_TopMsgProcess *mp = findTopMsgProcessFunc(type, env);
+    if (mp == NULL)
+        return false;
+    FREE_SYMBOL(mp->func);
+    mp->func = COPY_SYMBOL(func, TopMsgProcessFunc);
+    return true;
+}
+
 bool pushExecutionActivity(af_Code *bt, bool return_first, af_Environment *env) {
     af_Code *next;
     if (!getCodeBlockNext(bt, &next))
@@ -418,6 +494,18 @@ bool setFuncActivityToNormal(af_Code *bt, af_Environment *env) {
     return true;
 }
 
+static void runTopMessageProcess(af_Environment *env) {
+    af_Message **pmsg = &env->activity->msg_down;
+    while (*pmsg != NULL) {
+        af_TopMsgProcess *mp = findTopMsgProcessFunc((*pmsg)->type, env);
+        if (mp != NULL) {
+            GET_SYMBOL(mp->func)(*pmsg, env);
+            *pmsg = freeMessage(*pmsg);
+        } else
+            pmsg = &((*pmsg)->next);
+    }
+}
+
 void popActivity(af_Message *msg, af_Environment *env) {
     if (env->activity->prev != NULL) {
         af_Message *new_msg;
@@ -429,9 +517,12 @@ void popActivity(af_Message *msg, af_Environment *env) {
         env->activity->msg_down = NULL;
         connectMessage(&new_msg, env->activity->prev->msg_down);
         env->activity->prev->msg_down = new_msg;
-    } else if (msg != NULL) {  // 到顶 且 msg != NULL
-        gc_delReference(*(af_Object **)msg->msg);
-        freeMessage(msg);
+    } else {  // 到顶
+        if (msg != NULL) {
+            msg->next = env->activity->msg_down;
+            env->activity->msg_down = msg;
+        }
+        runTopMessageProcess(env);
     }
     env->activity = freeActivity(env->activity);
 }

+ 16 - 0
src/main.c

@@ -1,6 +1,15 @@
 #include <stdio.h>
 #include "aFun.h"
 
+void mp_ERROR_STR(af_Message *msg, af_Environment *env) {
+    char **pinfo = getMessageData(msg);
+    printf("ERROR\n");
+    if (pinfo == NULL || *pinfo == NULL)
+        return;
+    fprintf(stderr, "ERROR-STR INFO : %s\n", *pinfo);
+    free(*pinfo);
+}
+
 int main() {
     aFunInit();
     printf("Hello World\n");
@@ -12,6 +21,13 @@ int main() {
     addVarToProtectVarSpace(makeVar("object", 3, 3, 3,
                                     makeObject("object", 0, false, true, NULL, NULL, env)),
                             env);
+
+    {
+        DLC_SYMBOL(TopMsgProcessFunc) func = MAKE_SYMBOL(mp_ERROR_STR, TopMsgProcessFunc);
+        addTopMsgProcess("ERROR-STR", func, env);
+        FREE_SYMBOL(func);
+    }
+
     if (!enableEnvironment(env)) {
         fprintf(stderr, "Enable Error.\n");
         exit(EXIT_FAILURE);

+ 11 - 1
test/test_dlc.c

@@ -2,6 +2,10 @@
 #include <stdlib.h>
 #include "tool.h"
 
+int test_func(void) {
+    return 100;
+}
+
 int main() {
     atexit(dlcExit);
 
@@ -12,16 +16,22 @@ int main() {
     }
 
     typedef int func(int a);
+    typedef int test(void);
     NEW_DLC_SYMBOL(int, INT);
     NEW_DLC_SYMBOL(func, FUNC);
+    NEW_DLC_SYMBOL(test, TEST);
 
     DLC_SYMBOL(INT) a;
     DLC_SYMBOL(FUNC) fun;
+    DLC_SYMBOL(TEST) test_fun;
 
     a = READ_SYMBOL(dlc, "num", INT);
     fun = READ_SYMBOL(dlc, "test", FUNC);
+    test_fun = MAKE_SYMBOL(test_func, TEST);
+
+    int test_func_result = GET_SYMBOL(test_fun)();
 
-    printf("a = %d, test = %d\n", GET_SYMBOL(a), GET_SYMBOL(fun)(GET_SYMBOL(a)));
+    printf("a = %d, test = %d\n", GET_SYMBOL(a), GET_SYMBOL(fun)(test_func_result));
 
     FREE_SYMBOL(a);
     FREE_SYMBOL(fun);