K.O.(KeyFC Open Translation Toolset) 是目前正在开发的“开放版本”汉化工具的代号。
其中的汉化部分工具试验性的采用了代号为Chobits Application Server(CAS)的架构。
这个结构的特点为,程序全部由基于消息传递的模块动态组合而成。
前面的四回把架构的关键特征进行了抽象的描述,本来不打算写第五回的(因此这回叫4.5),但是...
在过去的一个多星期我埋头苦干,将CAS代码从头到尾的梳理了一遍。因此KO部分的工作暂停了下来... XD
更改的地方比较的多:很多功能被规范化,无数细小的错误(和潜在错误)得到了更正,部分核心代码简化... (还好以前写得算整齐,不然就晕了... =v=)
尽管总的架构没有太大改变,但是我觉得还是有必要作一下文档工作,避免以后自己忘了 :D
主要的更改点有:
1. CAS消息扩展功能的规范化
2. 线程和线程池的包装完善化
3. 意外对象(Exception Object)的完善化
--- CAS 消息 ---
听说Delphi 2007的Together更加的稳定,于是我也开始学着玩玩,发现这东西确实不错 =v=
Model支持与IDE完美的集成,只要几点鼠标,20秒下面的图就出来了 :P
照着讲...
* 增加BusMSG接口。
话说本次修订前,其实CAS总线并没有真的支持完全自定义的消息实例,因为发送消息的方法接受的是以BaseMSG为基类的对象... :P
后来我在一边讲的时候意识到了这一点,于是现在添加一个BusMSG接口,并且使得发送消息方法接受实现BusMSG接口的消息,真正的支持消息的自由实现。
(增加一个接口,而不是扩展原来的BaseMSG接口的原因是功能分离,用户模块仅需要看见对它们有意义的接口,不用关心总线内部发生的事情)
* 实现了前面提到的,较为通用"跨模块调用"(Inter-module call, IMC)消息支持。
本次修订之前,对于IMC的支持是硬写在消息队列核心的,因此不具有自定义实现以及扩展性。
现在添加一个MSG_Event接口,为消息在总线的传输添加通用的事件,然后将IMC消息支持实现在这些事件的基础上。
这样,不仅自定义性得到满足(可以重新实现自己的IMC消息),而且也具有比较好的扩展性(利用事件支持,还可以实现一切其它的功能)。
* 将扩展消息模单独块化。(上图中不可见)
本次修订之前,扩展消息和基本消息挤在一个模块里面。现在基本消息模块仅含有必须的消息接口,减少不需要扩展消息的模块的代码量。
* 优化扩展消息的实现。(上图中不可见)
可复制消息和可序列化消息的代码经过重新梳理和测试,效率和可靠性都得到提高。
--- 线程和线程池 ---
* 重写了线程回收代码
本次修订之前,对于需要强制回收的线程使用的是TerminateThread,这种方法不能有效回收系统资源,而且也不能给目标线程回收用户资源的机会。
现在则采用了改变线程上下文的方法,并且分两步回收线程: 首先强制生成一个例外,如果一定时间内还不能中止,再强制让线程自我中止。
若第一种方法成功,所有的资源应该得到完美的回收 (当然,前提是执行的程序有良好的意外处理机制);
第二种方法能够回收系统分配的线程资源以及部分已知的用户资源 (尽管不能完全回收,但是比TerminateThread什么都回收不了的好 =v=)。
另外,顺带重新包装了OS的一写同步对象,以保证必要时能够及时唤醒等待中的线程。
* 为工作线程增加接口
修订的过程中,我突然想起,分配线程给用户模块的时候用的居然是类.... |||||| 现在改正为接口了,同时对于线程对象的中止条件进行了完整的测试,保证不论线程以何种方式结束(自杀或者他杀 :P),都不会导致线程对象和线程池出问题。
Delphi包装的线程拥有良好的自定义性能。因为支持纯虚函数指针,任何类实现线程方法都可以通过工作线程成为一个独立的执行体,没有任何对象继承的要求。
--- 意外对象 ---
Delphi的另一个特色就是对意外处理有优良的包装,同过抛出意外处理异常情况能够提供比返回值有用很多倍的信息,而且随时随地,想抛就抛。
本次修订新增了一个独立的意外对象(而不是继承自默认的意外对象),特点就是,能够自动叠加(Stack)其它的意外对象,形成完整的"意外链",对于代码的除错非常的有用,特别是在没有源代码或者调试器的情况下。
简单的讲,就是在这个意外对象被抛出的时候,如果当前已经有一个已经抛出的对象,则新的意外对象将旧的自动"链接"到自己内部。
这个功能在许多语言里面几乎是无法想象的。比如Java中新的意外将会覆盖掉旧的意外;C++则更狠,如果抛出新的意外时旧还没释放,程序强制调用ExitProcess,世界太平...|||| (这就是为什么C++强烈不建议在Destructor中抛出异常)
新CAS的意外对象不仅可以提供文字和数字反馈,还可以提供出现意外的类(不仅仅是名字,而是一个类的引用),方法的名称,以及更加有用的信息: 一个意外分类代码。
这个分类代码表示了出现这个意外大致的原因,已经可能的问题。例如:
User类意外表示这个错误是由于程序员不小心引起的,比如提供了一个超过数组范围的编号;
Functional类意外表示这个意外是功能的一部分,比如,如果用户选择通过意外而不是返回值通知消息发送超时,将可能收到Functional类的意外;
Panic类意外表示可能出现了一些不寻常的问题,比如系统内存耗尽;
Internal类意外表示可能总线的代码有问题,这个时候就需要通知我来解决啦! :D
------
最后,来一张消息总线的全景。
(注意,程序未正式发布前,你所看到的东西都有可能改变.....尽管几率比较小......)