游戏开发论坛

 找回密码
 立即注册
搜索
查看: 3738|回复: 9

回调类中动态成员(事件)完全解决

[复制链接]

9

主题

102

帖子

343

积分

中级会员

Rank: 3Rank: 3

积分
343
发表于 2007-2-24 18:56:00 | 显示全部楼层 |阅读模式
大家直接调用宏即可
因为不用模版,每次RaiseEvent都要写出参数类型,如RaiseEvent(m_pClick,(int,long),aaa,bbb);
但是,更大的好处是,AddCallBack/RemoveCallBack时不用给出参数类型表!

代码的前面是List数据结构的实现,大家完全可以略过不看。
#include <iostream.h>
/////////////////////////////////////////////////////////////////////////////
template <class T> class IList
{
public:
virtual void VAdd(T* item)=0;
virtual void VRemove(int index)=0;
virtual void VClear()=0;
virtual int VGetCount()=0;
virtual T* VGet(int index)=0;
virtual void VSet(int index,T* val)=0;
};
/////////////////////////////////////////////////////////////////////////////
// note: int a[3] is : a[0],a[1],a[2]! so,a[0 to 3] will be int a[3+1]!
template <class T> class ArrayedList : public IList<T>
{
public:
virtual void VAdd(T* item);
virtual void VRemove(int index);
virtual void VClear();
virtual int VGetCount() { return m_Count; };
virtual T* VGet(int index){ if(index) return m_ppTs[index];return 0; };
virtual void VSet(int index,T* val){ if(index) m_ppTs[index]=val;};
~ArrayedList();
ArrayedList();
private:
T** m_ppTs;
public:
int m_Count;
};
template <class T> ArrayedList<T>::ArrayedList()
{
m_ppTs=new T*[0];
m_Count=0;
}
template <class T> ArrayedList<T>::~ArrayedList()
{
delete[] m_ppTs;
m_Count=0;
}
template <class T> void ArrayedList<T>::VAdd(T* item)
{
T** tmp=new T*[m_Count+1+1];
for (int i=1;i<=m_Count;i++)
tmp=m_ppTs;
delete[] m_ppTs;
m_ppTs=tmp;
m_ppTs[m_Count+1]=item;
m_Count+=1;
}
template <class T> void ArrayedList<T>::VClear()
{
delete[] m_ppTs;
m_ppTs=new T*[0];
}
template <class T> void ArrayedList<T>::VRemove(int index)
{
T** tmp=new T*[m_Count-1+1];
for (int i=1;i<=index-1;i++)
tmp=m_ppTs;
if (index<m_Count)
for (i=index+1;i<=m_Count;i++)
tmp[i-1]=m_ppTs;
m_Count-=1;
delete[] m_ppTs;
m_ppTs=tmp;
tmp=0;
}
//==============================================================================
class __obj{};
class CEvent
{
public:
typedef struct
{
__obj* pThis;
void(__obj::* pFunc)();
}CALLBACK;
ArrayedList<CALLBACK>* m_pCallBacks;
void Add(__obj*,void(__obj::*)());
void Remove(__obj*,void(__obj::*)());
CEvent();~CEvent();
};
CEvent::CEvent()
{
m_pCallBacks=new ArrayedList<CALLBACK>;
}
CEvent::~CEvent()
{
delete m_pCallBacks;
}
void CEvent::Add(__obj* pThis,void(__obj::* pFunc)())
{
if(m_pCallBacks->VGetCount())
for(int i=1;i<=m_pCallBacks->VGetCount();i++)
if(m_pCallBacks->VGet(i)->pThis==pThis||m_pCallBacks->VGet(i)->pFunc==pFunc) return;
CALLBACK* tmp=new CALLBACK;
tmp->pThis=pThis;
tmp->pFunc=pFunc;
m_pCallBacks->VAdd(tmp);
}
void CEvent::Remove(__obj* pThis,void(__obj::* pFunc)())
{
if(m_pCallBacks->VGetCount())
for(int i=1;i<=m_pCallBacks->VGetCount();i++)
if(m_pCallBacks->VGet(i)->pThis==pThis||m_pCallBacks->VGet(i)->pFunc==pFunc)
m_pCallBacks->VRemove(i);
}
//********************************************************
#define RaiseEvent(event,types,params)if(event->m_pCallBacks->VGetCount())for (int i=1;i<=event->m_pCallBacks->VGetCount();i++)(event->m_pCallBacks->VGet(i)->pThis->*((void(__obj::*)types)event->m_pCallBacks->VGet(i)->pFunc))params;
//--------------------------------------
#define AddCallBack(event,pthis,func)event->Add((__obj*) pthis,(void(__obj::*)())func);
//--------------------------------------
#define RemoveCallBack(event,pthis,func)event->Remove((__obj*) pthis,(void(__obj::*)())func);
//********************************************************
class CBtn
{
public:
CEvent* m_pClick;
CBtn();~CBtn();
void Init();
};
void CBtn::Init()
{
m_pClick=new CEvent;
cout<<btn is initialized!<<endl;
};
CBtn::CBtn()
{
cout<<btn is created!<<endl;
}
CBtn::~CBtn()
{
delete m_pClick;
}
////////////////////////////////////////////////////////////
class CWnd
{
public:
CBtn* m_pBtn;
void OnClick(int,long);
CWnd();~CWnd();void Init();
};
CWnd::CWnd()
{
cout<<wnd is created!<<endl;
};
CWnd::~CWnd()
{
delete m_pBtn;
}
void CWnd::Init()
{
m_pBtn=new CBtn;
m_pBtn->Init();
AddCallBack(m_pBtn->m_pClick,this,&CWnd::OnClick);
cout<<wnd is initialized!<<endl;
}
void CWnd::OnClick(int a,long b)
{
cout<<btn clicked\n this of CWnd=<<this<<\n<<params:<<a<<\n<<b<<endl;
char* i;cin>>i;
}
//////////////////////////////////////////////////////////
void main()
{
CWnd* pWnd=new CWnd;
pWnd->Init();
cout<<please enter an 1 to RAISE CLICK EVENT !;
int a;
cin>>a;
if(a==1)
RaiseEvent(pWnd->m_pBtn->m_pClick,(int,long),(111,222));
delete pWnd;
}

8

主题

716

帖子

716

积分

高级会员

Rank: 4

积分
716
发表于 2007-3-13 11:26:00 | 显示全部楼层

Re:回调类中动态成员(事件)完全解决

感谢分享~

121

主题

2029

帖子

2034

积分

金牌会员

Rank: 6Rank: 6

积分
2034
QQ
发表于 2007-3-14 16:19:00 | 显示全部楼层

Re:回调类中动态成员(事件)完全解决

此类方法网上已出现数种。不知道LZ可以稍微比较一下不?

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
发表于 2007-5-22 12:51:00 | 显示全部楼层

Re:回调类中动态成员(事件)完全解决

处理同一个事件,可以设置多个回调函数。

比如:
你有一个按钮TheButton,他有一个OnClick事件。
ClassA::TheButton_OnClick()
ClassB::TheButton_OnClick()
可以在几个函数中处理同一个事件。

关于IList数据结构:
当然你也可以重写。。。
ArrayedList: IList
这是动态数组。为了提高效率而不用链表。

0

主题

202

帖子

202

积分

中级会员

Rank: 3Rank: 3

积分
202
发表于 2007-6-19 00:39:00 | 显示全部楼层

Re:回调类中动态成员(事件)完全解决

何苦? 思维定式!

60

主题

1319

帖子

1319

积分

金牌会员

Rank: 6Rank: 6

积分
1319
发表于 2007-6-21 19:19:00 | 显示全部楼层

Re:回调类中动态成员(事件)完全解决

CEGUI里那套我觉得不错

154

主题

4567

帖子

4579

积分

论坛元老

Rank: 8Rank: 8

积分
4579
QQ
发表于 2007-6-21 20:15:00 | 显示全部楼层

Re:回调类中动态成员(事件)完全解决

Btn 是啥? -.-  

int a long b ? 是 WPARAM wParam LPARAM lParam 吧? 俄,看简写比较痛苦

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
发表于 2008-1-14 03:03:00 | 显示全部楼层

Re: Re:回调类中动态成员(事件)完全解决

shengkz: Re:回调类中动态成员(事件)完全解决

Btn 是啥? -.-  

int a long b ? 是 WPARAM wParam LPARAM lParam 吧? 俄,看简写比较痛苦


做试验用的,自定义的类,和微软没有关西。

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
发表于 2008-1-14 03:13:00 | 显示全部楼层

Re: Re:回调类中动态成员(事件)完全解决

lwevil: Re:回调类中动态成员(事件)完全解决

何苦? 思维定式!


java里的接口,什么action listener之类的,很恶心。

6

主题

35

帖子

49

积分

注册会员

Rank: 2

积分
49
QQ
发表于 2008-2-19 20:10:00 | 显示全部楼层

Re:回调类中动态成员(事件)完全解决

很好,很强大
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-20 04:33

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表