zoukankan      html  css  js  c++  java
  • 实现一个简单的事件订阅通知机制(Observer模式实现)

    //Base_Event.h
    #pragma once
    #include <list>
    
    enum Event_Type //事件类型
    {
        NET_REFRESH, //网络环境改变事件
        MSG_REFRESH, //消息改变事件
        UI_REFRESH,  //UI界面更新事件
    
        MAX_EVENT_LENGTH //事件种类长度
    };
    
    
    //事件处理接口,订阅该事件的类应该继承该接口,并实现HandleEvent()方法对事件进行处理
    class IEvent
    {
    public:
        virtual void HandleEvent() = 0;
    };
    
    
    class EventDispatcher
    {
    public:
        explicit EventDispatcher();
        ~EventDispatcher();
        void AddListener(Event_Type,IEvent *);                            //订阅事件
        void RemoverListener(Event_Type,IEvent *);                        //取消订阅事件
        void DispatchEvent(Event_Type ,const void *pEventData) const;    //分发事件并调用订阅该事件的所有对象处理该事件
    
        static EventDispatcher& getInstance();                            //单例模式,实现对象单一化
    
        static const void *m_pEventData ;                                //事件附加数据
    private:
         std::list<IEvent*> m_EventsList[MAX_EVENT_LENGTH];                //事件对象存储链表
    };
    
    extern EventDispatcher EDInstance;
    //Base_Event.cpp
    #include "Base_Event.h"
    #include <assert.h>
    
    const void* EventDispatcher::m_pEventData = NULL;
    
    EventDispatcher::EventDispatcher()
    {
            
    }
    
    EventDispatcher::~EventDispatcher()
    {
    
    }
    
    
    EventDispatcher EDInstance = EventDispatcher::getInstance();
    
    EventDispatcher& EventDispatcher::getInstance()
    {
        static EventDispatcher singleEntity;
    
        return singleEntity;
    }
    
    void EventDispatcher::AddListener(Event_Type et, IEvent *pEv)
    {
        assert(et < MAX_EVENT_LENGTH);
        m_EventsList[et].push_back(pEv);
    }
    
    
    void EventDispatcher::RemoverListener(Event_Type et,IEvent *pEv)
    {
        assert(et < MAX_EVENT_LENGTH);
    
        std::list<IEvent *>::iterator itor = std::find(m_EventsList[et].begin(), m_EventsList[et].end(), pEv);
        if (itor != m_EventsList[et].end())
        {
            m_EventsList[et].erase(itor);
        }
        
    }
    
    void EventDispatcher::DispatchEvent(Event_Type et, const void *pEventData)const
    {
        m_pEventData = pEventData;
        for (std::list<IEvent *>::const_iterator itor = m_EventsList[et].begin(); itor != m_EventsList[et].end(); itor++)
        {
            (*itor)->HandleEvent(); //遍历该事件链表,并调用订阅该事件所有对象处理方法
        }
    }
    //main.cpp
    #include <iostream>
    #include <string>
    #include "Base_Event.h"
    
    
    //Window1 可以用来模拟当后台数据发生变化,通知与该数据关联的所有窗口同步刷新处理该事件
    class Window1 :public IEvent
    {
    public :
        Window1()
        {
            //订阅UI_REFRESH事件
            EDInstance.AddListener(UI_REFRESH, this);
        }
        ~Window1()
        {
            //取消订阅UI_REFRESH事件
            EDInstance.RemoverListener(UI_REFRESH, this);
        }
    
        //实现IEvent接口,并实现对UI_CHANGED消息的处理
        virtual void HandleEvent() 
        {
            std::string strEvData((char *)EventDispatcher::m_pEventData);
            std::cout << "i am window1 and i got the UI_REFRESH event and the Event Data is = " << strEvData << std::endl;
        }
    
    };
    
    class Window2 :public IEvent
    {
    public:
        Window2()
        {
            //订阅UI_REFRESH事件
            EDInstance.AddListener(UI_REFRESH, this);
        }
        ~Window2()
        {
            //取消订阅UI_REFRESH事件
            EDInstance.RemoverListener(UI_REFRESH, this);
        }
    
        //实现IEvent接口,并实现对UI_REFRESH消息的处理
        virtual void HandleEvent()
        {
            std::string strEvData((char *)EventDispatcher::m_pEventData);
            std::cout << "i am window2 and i got the UI_REFRESH event and the Event Data is = " << strEvData << std::endl;
        }
    
    };
    
    int main()
    {
        Window1 win1; 
        Window2 win2;
        EDInstance.DispatchEvent(UI_REFRESH, std::string("to refresh the window UI").c_str()); //分发UI_REFRESH事件
    
        return 0;
    }
  • 相关阅读:
    P1964 【mc生存】卖东西
    到达型01背包---P1877 [HAOI2012]音量调节
    组合数学---P1358 扑克牌
    分组背包---P1757 通天之分组背包
    01背包---P2392 kkksc03考前临时抱佛脚
    背包DP 方案数
    完全背包---P1679 神奇的四次方数
    01-背包---P2663 越越的组队
    17、排序算法-希尔排序
    16、排序算法-插入排序
  • 原文地址:https://www.cnblogs.com/sunbing/p/4069018.html
Copyright © 2011-2022 走看看