继续 GeoPad. 数据结构
在GeoPad 中, 使用双向链表作为主数据结构, 关于选择这一数据结构的主要考虑:
1. 双向链表适合任意位置插入(主要是尾部添加), 任意位置删除, 以及遍历(双向遍历).
2. 双向链表知足序列性, 知足对象建立顺序的保持须要. app
除了双向链表以外, 还有一些别的辅助用数据结构, 稍后笔记. 函数
对链表的通常性操做有: this
append_obj(obj): 将 obj 对象添加到链表末尾. 这个函数同时还更新一些别的数据
结构, 别的数据结构之后分析. 主要可认为是append到双向链表. 设计
delete_single_obj(obj): 删除对象, 从链表中移除对该对象的引用. 当前这个函数可能处理
了多种事务, 能够适当考虑分离(如 unlink_obj 分离出去). 对象
find_objs(filter): 遍历全部几何对象, 查找知足 filter 所给条件的全部对象. 至关于简单的
遍历双向链表的状况.
彷佛能够实现相似的单个变体 find_one_obj(filter) 只找第一个知足条件的, 或最后一个?
遍历的通常形式: for (var obj = this.head_obj; obj != null; obj = obj.next_obj) ...
反向的扫描为: for (var obj = this.tail_obj; obj != null; obj = obj.prev_obj) ... 索引
======= 事务
除了使用双向链表以外, 为支持其它需求, 还有几种辅助的数据结构: 开发
1. Object[] highlighted_objs. 用于支持跟踪被高亮的对象. 构建对象上的点, 交点时, 须要
高亮一条线(圆)或两条线(圆)等.
2. Object[] selected_objs. 用于支持跟踪被选中的对象. 被选中的对象有顺序性. 对
被选中的对象可能要有多种运算须要, 可能将来实现为某种对象比较合适(? TODO)
3. {} obj_by_id. 使用几何对象 id 可快速查找到该对象的一个 map. 不须要遍历链表.
这个(索引)结构在 append_obj(), delete_single_obj() 中维护. io
另外, 在原来开发时为支持建立新对象, 引入了 tmp_head, tmp_tail 临时的对象概念, 如今
看起来这种引入不是很好, 它增长了复杂度, 代码又有重复, 应该想办法早点替代掉. (TODO)
(同时也就去掉了多余的函数: append_to_tmp(), clear_tmp_objs() 等)
关于高亮(highlight)的函数:
1. highlight_objs(obj): 高亮指定的 obj(多是一个 array), 并取消原有对象的高亮.
TODO: 也许加一个参数 keep_old, 不取消原有对象的高亮?
关于选择(selection)的函数:
1. select_objs(obj, keep_old): 选中指定的 obj(多是一个 array), 并取消原有选中,
根据 keep_old.
2. unselect_obj(obj): 取消指定对象的选中.
3. unselect_all(): 取消全部对象的选中.
TODO: 也许 unselect_obj(null) 能够取代 unselect_all(), 以减小一个函数?
对于 highlight 支持: 被高亮的对象, 还设置其 obj.highlight =true, 这样对象在绘制
的时候知道本身是被高亮的.
对于 selection支持: 被选中的对象, 设置其 obj.selected = true, 这样对象在绘制等
操做的时候, 知道本身是被选中的.
问题: 某些操做对这种状态信息有特殊须要的可能吗?
TODO: 因为上述数据存在一致性问题, 设计一个 self_check() 函数进行检查看起来是一个 不错的主意.