利用EventFilter正规化事件流

来源:互联网 发布:360家庭网络管理手机版 编辑:程序博客网 时间:2024/05/22 07:08

我们在开发BREW应用中,使用事件处理的场合非常之多,比如每个界面的HandleEvent,App的HandleEvent,Form,Widget等的HandleEvent。通常,我们设计实现时,对于正常,规则的事件流考虑的很充分,没有任何问题。 但是,对于异常不规则的事件流,往往编码时无法完整的预测,也就没有能进行相应的顾及。后果往往轻则逻辑异常,重则Crash死机。 比如,最典型的几种情况:

1。 Key事件流(Key Press, Key, Key Release)不按顺序到达HandleEvent,或者存在丢失

2。Pointer事件流(Down,Move,Up)不按顺序到达HandleEvent,或者存在丢失

3。 期望屏蔽过快的Key,Pointer操作,或者在某些特殊状态下(如打开文件,解码过程中)屏蔽Key,Pointer事件流

 

 

以上几种情况什么条件下会发生,这里不多说明, 但是肯定的是,在一个实际的需求空间和运行空间中,是100%存在发生的可能性的。 以前遇到过类似痛苦的TX应该印象尤为深刻。

 

OK, 闲话少说, 问题来了,我们如何处理那? 我们可以要求每个组件,界面,应用的事件处理设计时进行充分的考虑,进行充分的异常处理。 不过这对开发者的要求而言比较高,不是今天的重点。 今天,我建议一种一致的简单的处理方式,可以被方便的复用到任何应用开发中,那就是利用EventFilter。

 

EventFilter,顾名思义就是事件流的过滤器,将其置于每个期望使用其的HandleEvent的开头处即可,这样,事件流先交给EventFilter处理,EventFilter输出规则化的事件,该事件再流向原有的流程即可。

 

我们建议定义一个公共的IEventFilter接口,然后由不同种类的EventFilter类(组件)来实现之, 比如KeyEventFilter,PointerEventFilter等等, IEventFilter除了继承标准的IQI(为了扩展性)接口外,初期只需新增2个API即可, _FeedEvent, _RegCustFilter。 _FeedEvent接收事件(包括eCode,wParm,dwParm),返回过滤转换后的事件流(多个事件,以NULL结束,为了考虑将来可能存在的一个事件被Filter成多个事件,每个事件均包含eCode,wParm,dwParm), _RegCustFilter允许用户注册自定义的Filter Callback。 具体的实现中,每个具体的EventFilter对象内部需要维持自己的数据和状态,然后根据当前的状态和输入事件,按照制定的策略进行过滤并输出结果, 比如, PointerEventFilter的实现中,就可能在没有收到Down事件的情况下,直接收到Move事件时,FeedEvent的返回直接为NULL, 即该Move事件被过滤。 当然,也有可能采用另外一种策略,FeedEvent的返回直接为Down,Move,NULL, 即,转换为Down,Move。

 

对于EventFilter的实现,需要特殊说明的是,对于自身不支持的事件类型,应用直接以原值返回,不得做任何过滤或者转换; 如果希望过滤掉该事件,则直接返回NULL; 如果需要转换该事件,则返回转换后的事件(可能多个)以及在事件流的结尾加NULL;按照自身策略进行Filter后,如果存在用户注册的FilterCallback,则应该将结果再次交给CustFilter进行过滤并返回。

 

 

有了EventFilter以后,应用开发中该如何使用哪?? 我们假设已经实现了KeyEventFilter和PointerEventFilter两个具体的EventFilter类,然后在某个特定的Form的HandleEvent中使用:

a。 创建两个IEventFilter接口实例 pKeyFilter 和 pPointerFilter,分别类型为KeyEventFilter,PointerEventFilter

b。 以链式的方式,将多个Filter串接,实现组合过滤;  Eventout = PointerEventFilter(KeyEventFilter(EventIn))

c。 如果在解码时,需要屏蔽任何的Key和Pointer事件,则调用_RegCustFilter API注册自己的FilterCallback,在其中判断当前为解码状态时且事件为Key或者Pointer,统一返回NULL事件

 

 

本文仅提供一个可行的策略,希望对大家有帮助。

原创粉丝点击