美文网首页
minigui 4.0 源代码分析(一)

minigui 4.0 源代码分析(一)

作者: RonZheng2010 | 来源:发表于2020-11-22 20:10 被阅读0次

1. 配置文件

1.1 文件格式

Minigui的配置文件是标准的section - key - value格式。

# MiniGUI.cfg
[system]
gal_engine=pc_xvfb
defaultmode=360x480-16bpp

1.2 ETC_S 与 ETCSECTION

ETC_S对应整个配置文件,而ETCSECTION对应单个Section的数据。

对于ETC_S,

  • 成员sections[]是动态分配的ETCSECTION数组,保存section信息。
  • 成员section_nr_alloc是ETCSECTION数组的大小,而section_nr是数组中实际的ETCSECTION的数目。

对于ETCSECTION,

  • 成员name是Section名字
  • 成员keys和values长度相同。前者是键数组,后者相应的值数组。key_nr是键数目, key_nr_alloc()是数组大小。

1.3 加载配置文件 mg_InitMgEtc()

mg_InitMgEtc()负责加载配置文件。

  • 调用LookForEtcFile()得到配置文件名。其中,

    • 得到配置文件名,调用GetValueFromEtcFile(),尝试读取文件中的一个必需项,如果成功,则调用strcpy()将文件名保存在全局变量ETCFILEPATH[]中。
    char ETCFILEPATH [MAX_PATH + 1];
    
    • 得到配置文件目录时,首先读取环境变量MG_CFG_PATH,如果这个文件不行,则尝试minigui进程的工作目录。配置文件名为MiniGUI.cfg。
  • 调用LoadEtcFile()加载配置文件。

  • 打开文件。

  • 调用malloc()创建ETC_S实例,以及它的成员sections数组。这个实例保存在全局变量hMgEtc中,它实际上是一个ETC_S指针。

    GHANDLE hMgEtc = 0;
    
  • 调用etc_ReadSection()读取Section,包括其下的Key及Value。如果Section、Key、Value的数组长度超限,则调用realloc()拓展长度。

1.4 GetValueFromEtc()

GetValueFromEtc()从全局变量hMgEtc读取键值。

2. 数据块堆

2.1 BLOCKHEAP

BLOCKHEAP是数据块的堆,用于提高小结构的分配效率,如剪裁区域CLIPRGN等。

  • 数据块保存在一个数组中,成员heap指向这个数组。
  • 成员bd_size是数据块的大小。
  • 成员heap_size是数组的大小。
  • 成员free是第一个空闲数据块的索引,这个用于加快查找空闲块。

BLOCKHEAP的内存布局如下图。

  • 绿色部分是BLOCKHEAP结构。
  • 黄/橙色部分是数据块,包括图中的free block和used block。一是挨着的数据包部分,这是成员heap指向的数组,数组大小是heap_size。
  • 用户获取数据块时,优先从heap指向的数组这里获取。如果其中的数据包都已使用,则调用alloc()动态分配。在图中标示为special block。
  • 数据块包括两个部分,首先是起始地址的两字节标志,然后是真正的数据。标志的取值如下。

    #define BDS_FREE    0x0000   // 在heap数组中,未使用
    #define BDS_SPECIAL  0x0001  // 动态分配,不在heap数组中
    #define BDS_USED    0x0002  // 在heap数组中,已使用 
    

2.2 InitBlockDataHeap()

函数InitBlockDataHeap()初始化BLOCKHEAP。其中将成员heap置空。

2.3 BlockDataAlloc()

函数BlockDataAlloc()从BLOCKHEAP中得到数据块。

  • 如果heap数组还没有创建,则调用calloc()创建它。数组大小由heap_size和bd_size指定。
  • 在heap数组中搜索空闲的数据块(标志为BDS_FREE)。如果找到,返回它,标志设置为BDS_USED。
  • 如果没找到空闲数据块,则调用calloc()分配一个,返回它,标志设置为BDS_SPECIAL。

3. Hash表

3.1 HASH_TABLE

HASH_TABLE定义Hash表,RES_ENTRY是其中的表项。

关于RES_ENTRY,

  • source是数据,type是数据类型

  • flag标志位

  • key是键值。键值HASH_KEY实际上是一个DWORD。

    typedef DWORD RES_KEY; 
    
  • 成员next使表项可以链接成链表。

关于HASH_TABLE,

  • 成员entries是RES_ENTRY链表的数组,size是数组大小。 数组大小是固定的,使用Key2Idx()函数将key值映射到数组范围内。

    #define Key2Idx(t,key)   ((key)%((t)->size))
    
  • 成员函数init_hash_table()初始化Hash表。

  • 成员函数get_entry()根据key值得到表项RES_ENTRY。如果对应表项不存在,且参数指定了“新建”选项,则创建表项。

  • 成员函数remove_entry()移除键值。

相关文章

网友评论

      本文标题:minigui 4.0 源代码分析(一)

      本文链接:https://www.haomeiwen.com/subject/vubuiktx.html