Browse Source

feat: Object创建时调用API

SongZihuan 3 years ago
parent
commit
e0e2b62447
7 changed files with 101 additions and 10 deletions
  1. 9 0
      include/obj_api.h
  2. 1 0
      include/object.h
  3. 24 2
      src/core/object.c
  4. 0 2
      src/core/run.c
  5. 33 3
      src/main.c
  6. 1 0
      test/test_dlc.c
  7. 33 3
      test/test_env.c

+ 9 - 0
include/obj_api.h

@@ -0,0 +1,9 @@
+#ifndef AFUN__OBJ_API_H
+#define AFUN__OBJ_API_H
+
+/* Object void *data 管理 */
+typedef size_t obj_getDataSize(void);  // 获取data的大小
+typedef void obj_initData(void *data);  // 初始化data
+typedef void obj_freeData(void *data);  // 释放data的内容
+
+#endif //AFUN__OBJ_API_H

+ 1 - 0
include/object.h

@@ -1,6 +1,7 @@
 #ifndef AFUN__OBJECT_H_PUBLIC
 #define AFUN__OBJECT_H_PUBLIC
 #include "tool.h"
+#include "obj_api.h"
 
 typedef struct af_Object af_Object;
 typedef struct af_Inherit af_Inherit;

+ 24 - 2
src/core/object.c

@@ -15,12 +15,28 @@ static void freeAllObjectAPINode(af_ObjectAPINode *apin);
 static af_ObjectAPINode *findObjectDataAPINode(char *api_name, af_ObjectData *od);
 static int addAPIToObjectData(DLC_SYMBOL(objectAPIFunc) func, char *api_name, af_ObjectData *od);
 
+/*
+ * 函数名: makeObjectData_Pri
+ * 目标: 创建ObjectData
+ * 注意: af_ObjectData不是对外开放的结构体
+ * 注意: api不能为NULL
+ */
 static af_ObjectData *makeObjectData_Pri(char *id, bool free_api, af_ObjectAPI *api, bool allow_inherit) {
     af_ObjectData *od = calloc(sizeof(af_ObjectData), 1);
     od->id = strCopy(id == NULL ? "Unknow" : id);
 
-    // data通过调用api实现
-    od->size = 0;
+    obj_getDataSize *func = findAPI("obj_getDataSize", api);
+    obj_initData *init = findAPI("obj_initData", api);
+    if (func != NULL)
+        od->size = func();
+    else
+        od->size = 0;
+
+    if (od->size != 0) {
+        od->data = calloc(od->size, 1);
+        if (init != NULL)
+            init(od->data);
+    }
 
     od->api = api;
     od->free_api = free_api;
@@ -81,6 +97,12 @@ af_Object *makeObject(char *id, bool free_api, af_ObjectAPI *api, bool allow_inh
  * 对外API中, 创建对象的基本单位都是af_Object, 无法直接操控af_ObjectData
  */
 void freeObjectData(af_ObjectData *od) {
+    if (od->size != 0) {
+        obj_freeData *func = findAPI("obj_freeData", od->api);
+        if (func != NULL)
+            func(od->data);
+    }
+
     free(od->id);
     free(od->data);
     if (od->free_api)

+ 0 - 2
src/core/run.c

@@ -66,8 +66,6 @@ static bool checkInMsgType(char *type, af_Environment *env) {
 
 static void popLastActivity(af_Message *msg, af_Environment *env) {
     do {  // 如果返回一级后仍是执行完成则继续返回
-        if (env->activity->prev == NULL)
-            printf("top finished\n");
         if (env->activity->return_first) {
             if (msg != NULL) {
                 gc_delReference(*(af_Object **)msg->msg);

+ 33 - 3
src/main.c

@@ -10,14 +10,44 @@ void mp_ERROR_STR(af_Message *msg, af_Environment *env) {
     free(*pinfo);
 }
 
+size_t getSize(void) {
+    return sizeof(int *);
+}
+
+void initData(int **data) {
+    *data = calloc(sizeof(int), 1);
+    **data = 100;
+}
+
+void freeData(int **data) {
+    printf("**data = %d\n", **data);
+    free(*data);
+}
+
 int main() {
     aFunInit();
     printf("Hello World\n");
 
     af_Environment *env = makeEnvironment();
-    addVarToProtectVarSpace(makeVar("global", 3, 3,
-                                    makeObject("global", true, makeObjectAPI(), true, NULL, NULL, env)),
-                            env);
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        DLC_SYMBOL(objectAPIFunc) getSize_ = MAKE_SYMBOL(getSize, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) initData_ = MAKE_SYMBOL(initData, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) freeData_ = MAKE_SYMBOL(freeData, objectAPIFunc);
+        if (addAPI(getSize_, "obj_getDataSize", api) != 1)
+            return 2;
+        if (addAPI(initData_, "obj_initData", api) != 1)
+            return 2;
+        if (addAPI(freeData_, "obj_freeData", api) != 1)
+            return 2;
+
+        addVarToProtectVarSpace(makeVar("global", 3, 3,
+                                        makeObject("global", true, api, true, NULL, NULL, env)),
+                                env);
+        FREE_SYMBOL(getSize_);
+        FREE_SYMBOL(initData_);
+        FREE_SYMBOL(freeData_);
+    }
     addVarToProtectVarSpace(makeVar("object", 3, 3,
                                     makeObject("object", true, makeObjectAPI(), true, NULL, NULL, env)),
                             env);

+ 1 - 0
test/test_dlc.c

@@ -35,6 +35,7 @@ int main() {
 
     FREE_SYMBOL(a);
     FREE_SYMBOL(fun);
+    FREE_SYMBOL(test_fun);
 
     if (!freeLibary(dlc))
         exit(EXIT_FAILURE);

+ 33 - 3
test/test_env.c

@@ -1,13 +1,43 @@
 #include <stdio.h>
 #include "aFun.h"
 
+size_t getSize(void) {
+    return sizeof(int *);
+}
+
+void initData(int **data) {
+    *data = calloc(sizeof(int), 1);
+    **data = 100;
+}
+
+void freeData(int **data) {
+    printf("**data = %d\n", **data);
+    free(*data);
+}
+
 int main() {
     aFunInit();
 
     af_Environment *env = makeEnvironment();
-    addVarToProtectVarSpace(makeVar("global", 3, 3,
-                                    makeObject("global", true, makeObjectAPI(), true, NULL, NULL, env)),
-                            env);
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        DLC_SYMBOL(objectAPIFunc) getSize_ = MAKE_SYMBOL(getSize, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) initData_ = MAKE_SYMBOL(initData, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) freeData_ = MAKE_SYMBOL(freeData, objectAPIFunc);
+        if (addAPI(getSize_, "obj_getDataSize", api) != 1)
+            return 2;
+        if (addAPI(initData_, "obj_initData", api) != 1)
+            return 2;
+        if (addAPI(freeData_, "obj_freeData", api) != 1)
+            return 2;
+
+        addVarToProtectVarSpace(makeVar("global", 3, 3,
+                                        makeObject("global", true, api, true, NULL, NULL, env)),
+                                env);
+        FREE_SYMBOL(getSize_);
+        FREE_SYMBOL(initData_);
+        FREE_SYMBOL(freeData_);
+    }
     addVarToProtectVarSpace(makeVar("object", 3, 3,
                                     makeObject("object", true, makeObjectAPI(), true, NULL, NULL, env)),
                             env);