【可复用性程序设计】——事件触发

先定义一个最简化的事件数据结构

typedef struct{

    unsigned char event_flg;
    unsigned char event_cnt_buf[event_flg_wide];
    void (*pEventCallback[event_flg_wide])(void);
}event;如果你的事件比较复杂,你可以继续往数据结构里添加对象成员,但是我不会这么干,我会抽象出一个事件类,然后通过继承派生出更丰富的子类。

事件触发具体实现如下:event.cpp
#include <iostream>
#include "event.h"
using namespace std;

event msg_event;

void msg_event_init(void)
{}

//注册消息响应函数
void event_install_callback(unsigned char fn_index, void pfn(void))
{
  if(fn_index < event_flg_wide)
  {
    msg_event.pEventCallback[fn_index] = pfn;
  }
}

//卸载消息响应函数
void event_uninstall_callback(unsigned char fn_index)
{
  if(fn_index < event_flg_wide)
  {
    msg_event.pEventCallback[fn_index] = NULL;
  }
}

void close_all_msg(event event_t )
{
    unsigned char i = 0;

    event_t.event_flg = 0;

    for(i=0;i<event_flg_wide;i++)
        event_t.event_cnt_buf[i] = 0;

    for(i=0;i<event_flg_wide;i++)
        event_t.pEventCallback[i] = NULL;
}

void msg_event_rountine(void)
{
    cout << "msg_event_rountine!" << endl;
}

//消息事件主线程
void msg_event_main_thread(void)
{
    unsigned char i;
    //监测到事件消息
    if(msg_event.event_flg)
    {
        //累计消息条目
        for(i=0;i<event_flg_wide;i++)
        {
            if(msg_event.event_flg&(1<<i))
            {
                msg_event.event_flg &= (~(1<<i));
                msg_event.event_cnt_buf[i]++;
            }
        }
    }
    else
    {
        //关掉负载
    }

    //执行消息响应
    for(i=0;i<event_flg_wide;i++)
    {
        if(msg_event.event_cnt_buf[i])
        {
            if(msg_event.pEventCallback != NULL)
            {
                msg_event.pEventCallback[i]();
                msg_event.event_cnt_buf[i]--;
                break;
            }
        }
    }
}

头文件event.h

#ifndef EVENT_H
#define EVENT_H

#ifndef FALSE
  #define  FALSE  0x00u
#endif
#ifndef TRUE
  #define  TRUE   0x01u
#endif

#ifndef NULL
  #define  NULL   0x00u
#endif

#define event_flg_wide  8

typedef struct{
    unsigned char event_flg;
    unsigned char event_cnt_buf[event_flg_wide];
    void (*pEventCallback[event_flg_wide])(void);
}event;
extern event msg_event;

void msg_event_init(void);
void msg_event_main_thread(void);
void event_install_callback(unsigned char fn_index, void pfn(void));
void event_uninstall_callback(unsigned char fn_index);
void msg_event_rountine(void);
void close_all_msg(event event_t );

#endif // EVENT_H

在main函数中注册两个事件,触发一下试试

  msg_event_init();

    event_install_callback(0,msg_event_rountine);
    event_install_callback(1,msg_event_rountine);
    msg_event.event_flg |= (1<<0)|(1<<1);
    while(1){
    msg_event_main_thread();
    }

 

测试工程放在网盘http://pan.baidu.com/s/1gdy2dhT

【可复用性程序设计】——事件触发

时间: 2024-11-07 16:41:59

【可复用性程序设计】——事件触发的相关文章

Android Activity 和 ViewGroup中事件触发和传递机制

1.在只有Activity的情况: 1)Touch事件触发流程: 首先触发dispatchTouchEvent 然后触发onUserInteraction 再次onTouchEvent 如果是点击的话,紧跟着下列事件(点击分俩步,ACTION_DOWN,ACTION_up) 触发dispatchTouchEvent 再次onTouchEvent 当ACTION_up事件时不会触发onUserInteraction(可查看源代码) 2)键盘事件触发流程 首先触发dispatchKeyEvent 然

高级程序设计-事件

作者:zccst 一.事件流标准:DOM事件流中,实际的目标在捕获阶段不会接收到事件.即捕获从document到body就停止了.在处于目标阶段,事件在div上发生,并在事件处理中被看成冒泡阶段的一部分.实际:在捕获阶段会涉及,结果有两个机会在目标对象上操作事件. 二.事件处理程序(事件监听器)事件处理程序:HTML,DOM0级,DOM2级 HTML:<input type="button" value="ClickMe" onclick="aler

C#事件触发机制

C#的事件触发机制,类似于c++的回调函数机制 我先简单说一下,委托和事件的实质,后期再重开一篇博文来详细说 委托:指向方法的指针,类似于C的函数指针 事件:是一个可以存放0个或多个方法指针的数据结构  .......... 在一次编译后会为其生成一个类等等的就以后另开博文说了 看看触发机制 方便理解,来个通俗一点的图 事件触发源类 class cclass { private char i; public delegate void ichanged(cclass s); public eve

U3D Trigger事件触发

使用Trigger事件触发,可以达到虽然触发了,可是不改变任何效果. 这个是进入时候触发的: void OnTriggerEnter2D(Collider2D other) { print (other.transform.name); } 退出触发: void OnTriggerExit2D(Collider2D other) { print (other.transform.name + "-----"); } 停留时触发: void OnTriggerStay2D(Collide

点击label事件触发两次的坑

今天帮群里的朋友看一段代码的时候偶然间遇到一个label的坑,点击label的时候,监听的click事件被执行两次: 具体代码如下: 1 <div id="test"> 2 <input type="checkbox" name="abc" id="abc"/> 3 <label for="abc">3423432432432432</label> 4 <

Zendframework 模块加载事件触发顺序。

模块加载时事件触发的时间顺序: 1.  loadModule.resolve(ModuleEvent::EVENT_LOAD_MODULE_RESOLVE):模块将被加载时触发,事件监听者将模块名解析成类的实例.监听者使用getModuleName()获取模块名. 2.  loadModule(ModuleEvent::EVENT_LOAD_MODULE):一旦模块被解析成对象后,本事件会被触发,与之相对的事件监听者会加载模块(将新建的对象传递给所有的监听者). 3.  mergeConfig(

Fastclick 导致click事件触发两次的问题

我在移动web上使用Fastclick这个库去解决300ms延迟问题,但是在安卓4.2下的webview中引发了另一个比较奇怪的bug. 在A页面中有个 a button,在B页面中有个 b button,a和b都在同一个position,给a和b都注册一个click事件.a的click事件触发后跳转到B页面.当a被点击后调到B页面,你会发现b按钮的click事件也被触发了. 没错,事件'穿透'了两个页面! 但其实并没有穿透,点击a按钮时,其实有如下两个动作: fastclick用touchst

Javascript事件触发顺序

html标签是有子和父的,这个时候就出现了事件触发顺序的问题,比如: <!DOCTYPE html> <html> <head> <style> .first{ border:solid #FF0000 } .second{ border:solid #00FF00 } .third{ border:solid #0000FF } </style> <script src="http://libs.baidu.com/jquery

浅谈Android onClick与onLongClick事件触发的问题

之前做按钮的点击事件一直没有注意一些细节,今天做了一个按钮需要有点击和长点击触发不同效果,直接让Activity implements OnClickListener, OnLongClickListener然后添加了相应的处理函数. @Override public void onClick(View v) { // TODO Auto-generated method stub } @Override public boolean onLongClick(View v) { // TODO