到第十天,很高兴啊,已经完成了大概三分之一的内容了!感觉写这个笔记,对自己还是很有用的。平日里看这种书,难免赶进度,草草浏览过。但是也因为要写笔记的因素,看得会相对认真一点。在回顾的时候看看自己以前的笔记,就会更快理清思路。
今天一开始,还是要继续昨天的内存管理内容。说来,对于内存管理这块,我还是真有点意犹未尽呢,接下来在后面还会继续有涉及。闲言少叙,进入正题。继续优化内存管理。我们昨天在方法三、四中讨论了如果可用内存小而多而散的情况,届时管理信息不够用。那么我们现在采用一种向上舍入的方法(roundup)。我们编写一些函数,把内存的大小按0x1000字节为单位向上舍入。这里引用一下源程序:
unsigned int memman_alloc_4k(struct MEMMAN *man, unsigned int size) { unsigned int a; size = (size + 0xfff) & 0xfffff000; a = memman_alloc(man, size); return a; } int memman_free_4k(struct MEMMAN *man, unsigned int addr, unsigned int size) { int i; size = (size + 0xfff) & 0xfffff000; i = memman_free(man, addr, size); return i; }
请看这句:
size = (size + 0xfff) & 0xfffff000;
常规方法虽然很好理解,但是却慢。因此采用最上面的方法。
接下来讲今天的第二个很重要的东西——sheet图层。采用原书的截图:
因为前面的鼠标还有一个大毛病:它像一块橡皮擦,走到哪把原图都破坏了。因此引入sheet的概念,在后面的窗口中也会有很多应用。值得一提的是,关于图层的程序开发,作者也是经历了一个不那么顺利的过程。基本上是这个思路:当前什么需求,只要完成这个需求就可以了,后期再有别的需求的时候,或者发现了缺陷,再一步步改进。了解这样的一个过程才能真正知其然,并且知其所以然。鼠标的问题如何解决?如果鼠标的背景色是透明色就好了!好的,就照这个思路,我们建立了第一个管理多重图层的结构:struct SHTCTL。这里需要着重解释其中的一个参数top。top代表最上面图层的高度。那么什么是高度呢?显示器像素坐标,横为x,竖为y,可以想象存在一个z,垂直于屏幕,向外指。高度最大的那张图层,就是能够完全显示在屏幕上的那张图层,你可以理解成鼠标。而高度最低的图层,那就是背景桌面了吧。具体的SHTCTL的结构,请看下图:
对于sheet的操作,重要的函数有完成调整图层高度关系的updown函数,还有让图层左右上下移动的slide函数,还有refresh刷新函数。updown的数据结构操作就像对队列进行元素的插入,不同点是该元素本就是属于队列的。slide函数很简单,只用把图层的新的位置坐标赋予图层即可。refresh函数需要着重说明。最初的refresh函数思路很简单:只要把所有图层从下到上都画出来不就行了,而透明色的思想如何体现呢?例如鼠标,我们不想显示鼠标的背景色,只要把该色设为背景色,然后做一个if判断,若果该像素等于背景色,则不再往上画。透明背景的问题解决了,但不觉得这种刷新方法很没必要嘛?首先说没必要在哪呢?鼠标指针最多只有16*16的像素,若稍微一动,就要刷新320*200=64000个像素,非常的没必要吧。
接下来进行改进,所说改进,但是刷新的思路还是在那,就是从头到尾一张张画,只不过刷新范围减小了。新的refreshsub指定刷新范围,此处的范围用两对绝对坐标,即屏幕上的显示坐标来表示。根据新的refreshsub再写新的refresh。注意,新的refresh完成的功能是,指定图层,以及相对坐标(相对于指定图层的坐标),然后刷新。为什么是相对坐标呢?因为往往我们知道一些图像在图层中的坐标,却不知道在屏幕上的坐标,那要进行计算,就把计算交给程序进行吧。
但是呢,即便这样,refreshsub还得改进。作者还真是自我要求高呀。但这里就不说了,因为不是很重要。
好了,今天的内容结束了!期待明天的笔记!!!