创建类的过程

 创建结构体类型

在代码中,首先定义了一个名为 lv_obj_t 的结构体类型,并在该结构体中定义了坐标、大小和父级对象等基本属性

struct _lv_obj_t{
    mp_obj_base_t base;             // 必须以这个开头
    int16_t x;
    int16_t y;
    uint32_t width;
    uint32_t height;
    lv_obj_t *parent;
};

 创建字典表

使用 STATIC const mp_rom_map_elem_t 定义了一个名为 lv_obj_locals_dict_table 的字典表,该字典表为空。

// 定义 lv_obj_t 类型的字典
STATIC const mp_rom_map_elem_t lv_obj_locals_dict_table[] = {};

 利用宏定义将字典表转换成对象

使用 MP_DEFINE_CONST_DICT 宏定义将字典表转换成对象 lv_obj_locals_dict

// 把字典转换成对象
STATIC MP_DEFINE_CONST_DICT(lv_obj_locals_dict, lv_obj_locals_dict_table);

 创造类类型对象

使用 STATIC const mp_obj_type_t 定义了一个名为 lv_type_obj 的类型对象。该类型对象包含类型信息、类名、类成员字典、构造函数和父类等属性。其中,构造函数为 lv_obj_make_new

// 定义 lv_type_obj 类型对象
STATIC const mp_obj_type_t lv_type_obj = {
    { &mp_type_type },              // 类型信息
    .name = MP_QSTR_obj,            // 类名
    .locals_dict = (mp_obj_dict_t *)&lv_obj_locals_dict,    // 类成员字典
    .make_new = lv_obj_make_new,    // 构造函数
    .parent = NULL,                 // 父类
};

 创造构造函数

定义了一个名为 lv_obj_make_new 的构造函数。该构造函数接受一个参数列表,解析出父级对象,并分配内存空间并返回一个 mp_obj_t 对象。

// 定义 lv_obj_make_new 构造函数
STATIC mp_obj_t lv_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args){
    // 检查参数
    mp_arg_check_num(n_args, n_kw, 0, 1, false);

    // 分配内存空间
    lv_obj_t *self = m_new_obj(lv_obj_t);
    self->base.type = type;         // 指定数据类型

    // 解析参数
    if(n_args > 0 && &lv_type_obj == mp_obj_get_type(args[0])){
        self->parent = (lv_obj_t *)args[0];
    }

    return MP_OBJ_FROM_PTR(self);   // 返回对象
}

 代码总览

(包含所创建的所有方法和类)

STATIC mp_obj_t lv_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args);
typedef struct _lv_obj_t lv_obj_t;//改名

// 1. 定义类型的字典
STATIC const mp_rom_map_elem_t lv_obj_locals_dict_table[] = {};


// 2. 把字典转换成对象
STATIC MP_DEFINE_CONST_DICT(lv_obj_locals_dict, lv_obj_locals_dict_table);  

// 3. 定义类结构
STATIC const mp_obj_type_t lv_type_obj = {
    { &mp_type_type },                                      // 类类型定义
    .name = MP_QSTR_obj,                                    // 类名
    .locals_dict = (mp_obj_dict_t *)&lv_obj_locals_dict,    // 类成员字典
    .make_new = lv_obj_make_new,
    .parent = NULL,
};

// 5. 定义数据类型
struct _lv_obj_t{
    mp_obj_base_t base;         // 必须以这个开头
    int16_t x;
    int16_t y;
    uint32_t width;
    uint32_t height;
    lv_obj_t *parent;
};

// 4. 定义构造函数(类型,按位置传递参数数量,按字典传递参数熟练,参数列表)
STATIC mp_obj_t lv_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args){
    // 可以传入一个参数,i也可以不传入参数
    // 传入得参数就是父级标签
    printf("调用了构造方法,传入%d个参数\n", n_args);

    // 检查参数(按位置参数得数量,按字典参数的数量,最参数要求,最大参数要求,是否允许按字典传值)
    mp_arg_check_num(n_args, n_kw, 0, 1, false);

    // m_malloc(sizeof(lv_obj_t));
    lv_obj_t *self = m_new_obj(lv_obj_t);   // 开辟类空间(SELF)
    self->base.type = type;                 // 制定数据类型(非常重要)
    // self->base.type = &lv_type_obj;
    if(n_args >0 && &lv_type_obj == mp_obj_get_type(args[0])){
        printf("确定是父级对象\n");
        self->parent = (lv_obj_t *)args[0];
    }

    return MP_OBJ_FROM_PTR(self);       // 返回对象
}


// ################################## 第一步 添加模块 ################################## 

// 1. 创建模块字典 MP_QSTR_ __name__
STATIC const mp_rom_map_elem_t lvgl_globals_table[] = {
    { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_lvgl) },       // 模块的名称

    // 方法定义的3. 加入到字典中
    { MP_ROM_QSTR(MP_QSTR_print), MP_ROM_PTR(&lv_print_obj) },          // 无参数方法
    { MP_ROM_QSTR(MP_QSTR_hello), MP_ROM_PTR(&lv_hello_obj) },          // 带一个参数的方法
    { MP_ROM_QSTR(MP_QSTR_add), MP_ROM_PTR(&lv_add_obj) },              // 带两个参数的方法
    { MP_ROM_QSTR(MP_QSTR_append), MP_ROM_PTR(&lv_append_obj) },              // 带两个参数的方法

    // 静态常量
    { MP_ROM_QSTR(MP_QSTR_INTVALUE), MP_ROM_INT(100)},
    { MP_ROM_QSTR(MP_QSTR_BOOLVALUE), MP_ROM_FALSE},

    // 类型定义
    { MP_ROM_QSTR(MP_QSTR_obj), MP_ROM_PTR(&lv_type_obj) },
    { MP_ROM_QSTR(MP_QSTR_div), MP_ROM_PTR(&lv_type_div) },
    { MP_ROM_QSTR(MP_QSTR_span), MP_ROM_PTR(&lv_type_span) },
    { MP_ROM_QSTR(MP_QSTR_ashan), MP_ROM_PTR(&lv_type_ashan) },
};


// 2. 将元素数组转换成字典对象
STATIC MP_DEFINE_CONST_DICT(lvgl_globals, lvgl_globals_table);          // 转换成字典对象

// 3. 定义模块
const mp_obj_module_t mp_mod_lvgl = {
    .base = { &mp_type_module },                    // 类型指向(模块的类型恒定为 &mp_type_module)
    .globals = (mp_obj_dict_t *)&lvgl_globals,      // 指向字典
};

// 4. 注册模块到系统
MP_REGISTER_MODULE(MP_QSTR_lvgl, mp_mod_lvgl);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值