游戏开发论坛

 找回密码
 立即注册
搜索
12
返回列表 发新帖
楼主: hhackerbox

最近突然感觉自己很强。

[复制链接]

1

主题

88

帖子

93

积分

注册会员

Rank: 2

积分
93
QQ
发表于 2009-10-24 23:50:00 | 显示全部楼层

Re:最近突然感觉自己很强。

果然牛B,完全没看懂

1

主题

17

帖子

18

积分

新手上路

Rank: 1

积分
18
 楼主| 发表于 2009-10-26 16:27:00 | 显示全部楼层

Re:最近突然感觉自己很强。

assent 事件处理
class SERVER_DECL EventableObject
{
        //申明两个友元类
        friend class EventMgr;
        friend class EventableObjectHolder;

protected:
        //删除一个事件
        void event_RemoveEvents();
        //删除某类事件
        void event_RemoveEvents(uint32 EventType);
        void event_ModifyTimeLeft(uint32 EventType, uint32 TimeLeft,bool unconditioned=false);
        void event_ModifyTime(uint32 EventType, uint32 Time);
        void event_ModifyTimeAndTimeLeft(uint32 EventType, uint32 Time);
        bool event_HasEvent(uint32 EventType);
        void event_RemoveByPointer(TimedEvent * ev);
        //得到事件的场景ID
        ASCENT_INLINE int32 event_GetCurrentInstanceId() { return m_event_Instanceid; }

public:
        uint32 event_GetEventPeriod(uint32 EventType);
        // Public methods
        EventableObject();
        virtual ~EventableObject();

        ASCENT_INLINE bool event_HasEvents() { return m_events.size() > 0 ? true : false; }
        //增加一个事件
        void event_AddEvent(TimedEvent * ptr);
        //重置所有事件
        void event_Relocate();
       
        // this func needs to be implemented by all eventable classes. use it to retreive the instance
        // id that it needs to attach itself to.
       
        virtual int32 event_GetInstanceID() { return -1; }

protected:

        int32 m_event_Instanceid;
        FastMutex m_lock;
        EventMap m_events;
        EventableObjectHolder * m_holder;
       
};
//EventMap被定义为typedef multimap<uint32, TimedEvent*> EventMap;因为同一类型的事件可能有许多种,至于multimap处理效率怎么样呢
我还是倾向于用map<int list<TimedEvent *>> 这样操作起来比较简单。或者可以用一个优先级别的list;
增加事件的时候
void EventableObject::event_AddEvent(TimedEvent * ptr)
{
        m_lock.Acquire();

        if(!m_holder)
        {
                m_event_Instanceid = event_GetInstanceID();
                m_holder = sEventMgr.GetEventHolder(m_event_Instanceid);
        }

        ptr->IncRef();
        ptr->instanceId = m_event_Instanceid;
        pair<uint32,TimedEvent*> p(ptr->eventType, ptr);
        m_events.insert( p );
        m_lock.Release();

        /* Add to event manager */
        if(!m_holder)
        {
                /* relocate to -1 eventholder :/ */
                m_event_Instanceid = -1;
                m_holder = sEventMgr.GetEventHolder(m_event_Instanceid);
                ASSERT(m_holder);
        }

        m_holder->AddEvent(ptr);
}
把事件插入到m_events映射列表里和m_holder->AddEvent(ptr)事件钩子,事件钩子从那里来的呢,m_holder = sEventMgr.GetEventHolder(m_event_Instanceid);
接下来看看m_holder,sEventMgr.

class EventableObjectHolder
{
public:
        EventableObjectHolder(int32 instance_id);
        ~EventableObjectHolder();

        void Update(uint32 time_difference);

        void AddEvent(TimedEvent * ev);
        void AddObject(EventableObject * obj);

        ASCENT_INLINE uint32 GetInstanceID() { return mInstanceId; }

protected:
        int32 mInstanceId;
        Mutex m_lock;
        EventList m_events;

        Mutex m_insertPoolLock;
        typedef list<TimedEvent*> InsertableQueue;
        InsertableQueue m_insertPool;
};

这里有两个事件列表,这个是为了处理的时候,避免资源竞争,用空间换时间的一个策略。这样我们我们的线程update遍历处理m_events时,在其他线程处理的时
其他场景线程也可以给我们的场景处理线程压入事件。
类比较简单。只有增加事件,处理事件,需要说明的所有这些都是基于场景的int32 mInstanceId,对象加入事件
void EventableObject::event_AddEvent(TimedEvent * ptr)
{
        m_lock.Acquire();

        if(!m_holder)
        {
                m_event_Instanceid = event_GetInstanceID();
                m_holder = sEventMgr.GetEventHolder(m_event_Instanceid);
        }

        ptr->IncRef();
        ptr->instanceId = m_event_Instanceid;
        pair<uint32,TimedEvent*> p(ptr->eventType, ptr);
        m_events.insert( p );
        m_lock.Release();

        /* Add to event manager */
        if(!m_holder)
        {
                /* relocate to -1 eventholder :/ */
                m_event_Instanceid = -1;
                m_holder = sEventMgr.GetEventHolder(m_event_Instanceid);
                ASSERT(m_holder);
        }

        m_holder->AddEvent(ptr);
}
上边函数的代码,说明事件的场景ID,事件钩子EventableObjectHolder 场景ID.因为所有的事件都是在场景线程里处理的。
if(!m_holder)
{
        m_event_Instanceid = event_GetInstanceID();
        m_holder = sEventMgr.GetEventHolder(m_event_Instanceid);
}
ptr->IncRef();
ptr->instanceId = m_event_Instanceid;
        pair<uint32,TimedEvent*> p(ptr->eventType, ptr);

事件对象,其实就是处理事件的参数,函数指针的集合
struct SERVER_DECL TimedEvent
{
        TimedEvent(void* object, CallbackBase* callback, uint32 type, time_t time, uint32 repeat, uint32 flags) :
                obj(object), cb(callback), eventType(type), eventFlag(flags), msTime(time), currTime(time), repeats(repeat), deleted(false),ref(0) {}
        //
        这两个想到与对象成员函数       
        void *obj;
        CallbackBase *cb;
        //一下控制事件的生命周期与执行的
        //事件类型
        uint32 eventType;
        //标记
        uint16 eventFlag;
        //时间
        time_t msTime;
        //当前时间
        time_t currTime;
        //重复执行的次数
        uint16 repeats;
        //是否删除
        bool deleted;
        //事件发生场景环境
        int instanceId;
        //引用计数
        volatile long ref;

        static TimedEvent * Allocate(void* object, CallbackBase* callback, uint32 flags, time_t time, uint32 repeat);

#ifdef WIN32
        void DecRef()
        {
                InterlockedDecrement(&ref);
                if(ref <= 0)
                {
                        delete cb;
                        delete this;
                }
        }

        void IncRef() { InterlockedIncrement(&ref); }
#else

        /* burlex: if anyone knows how to do the equivilent of InterlockedIncrement/Decrement on linux feel free
           to change this, I couldn't find the atomic functions anymore though :*( */

        void IncRef() { ++ref; }
   
        void DecRef()
        {
                --ref;
                if(ref <= 0)
                {
                         delete cb;
                         delete this;
                }
        }
#endif

};
最后事件管理,是个单件模板,

typedef map<int32, EventableObjectHolder*> HolderMap;

class SERVER_DECL EventMgr : public Singleton < EventMgr >
{
        friend class MiniEventMgr;
public:
        template <class Class>
                void AddEvent(Class *obj, void (Class::*method)(), uint32 type, uint32 time, uint32 repeats, uint32 flags)
        {
                // create a timed event
                TimedEvent * event = new TimedEvent(obj, new CallbackP0<Class>(obj, method), type, time, repeats, flags);

                // add this to the object's list, updating will all be done later on...
                obj->event_AddEvent(event);
        }

        template <class Class, typename P1>
                void AddEvent(Class *obj, void (Class::*method)(P1), P1 p1, uint32 type, uint32 time, uint32 repeats, uint32 flags)
        {
                // create a timed event
                TimedEvent * event = new TimedEvent(obj, new CallbackP1<Class, P1>(obj, method, p1), type, time, repeats, flags);

                // add this to the object's list, updating will all be done later on...
                obj->event_AddEvent(event);
        }

        template <class Class, typename P1, typename P2>
                void AddEvent(Class *obj, void (Class::*method)(P1,P2), P1 p1, P2 p2, uint32 type, uint32 time, uint32 repeats, uint32 flags)
        {
                // create a timed event
                TimedEvent * event = new TimedEvent(obj, new CallbackP2<Class, P1, P2>(obj, method, p1, p2), type, time, repeats, flags);

                // add this to the object's list, updating will all be done later on...
                obj->event_AddEvent(event);
        }

        template <class Class, typename P1, typename P2, typename P3>
                void AddEvent(Class *obj,void (Class::*method)(P1,P2,P3), P1 p1, P2 p2, P3 p3, uint32 type, uint32 time, uint32 repeats, uint32 flags)
        {
                // create a timed event
                TimedEvent * event = new TimedEvent(obj, new CallbackP3<Class, P1, P2, P3>(obj, method, p1, p2, p3), type, time, repeats, flags);

                // add this to the object's list, updating will all be done later on...
                obj->event_AddEvent(event);
        }

        template <class Class, typename P1, typename P2, typename P3, typename P4>
                void AddEvent(Class *obj, void (Class::*method)(P1,P2,P3,P4), P1 p1, P2 p2, P3 p3, P4 p4, uint32 type, uint32 time, uint32 repeats, uint32 flags)
        {
                // create a timed event
                TimedEvent * event = new TimedEvent(obj, new CallbackP4<Class, P1, P2, P3, P4>(obj, method, p1, p2, p3, p4), type, time, repeats, flags);

                // add this to the object's list, updating will all be done later on...
                obj->event_AddEvent(event);
        }

        template <class Class> void RemoveEvents(Class *obj) { obj->event_RemoveEvents(-1); }
        template <class Class> void RemoveEvents(Class *obj, int32 type)
        {
                obj->event_RemoveEvents(type);
        }

        template <class Class> void ModifyEventTimeLeft(Class *obj, uint32 type, uint32 time,bool unconditioned=true)
        {
                obj->event_ModifyTimeLeft(type, time,unconditioned);
        }

        template <class Class> void ModifyEventTimeAndTimeLeft(Class *obj, uint32 type, uint32 time)
        {
                obj->event_ModifyTimeAndTimeLeft(type, time);
        }

        template <class Class> void ModifyEventTime(Class *obj, uint32 type, uint32 time)
        {
                obj->event_ModifyTime(type, time);
        }

        template <class Class> bool HasEvent(Class *obj, uint32 type)
        {
                return obj->event_HasEvent(type);
        }

        EventableObjectHolder * GetEventHolder(int32 InstanceId)
        {
                HolderMap::iterator itr = mHolders.find(InstanceId);
                if(itr == mHolders.end()) return 0;
                return itr->second;
        }

        void AddEventHolder(EventableObjectHolder * holder, int32 InstanceId)
        {
                holderLock.Acquire();
                mHolders.insert( HolderMap::value_type( InstanceId, holder) );
                holderLock.Release();
        }

        void RemoveEventHolder(int32 InstanceId)
        {
                holderLock.Acquire();
                mHolders.erase(InstanceId);
                holderLock.Release();
        }

        void RemoveEventHolder(EventableObjectHolder * holder)
        {
                holderLock.Acquire();
                HolderMap::iterator itr = mHolders.begin();
                for(; itr != mHolders.end(); ++itr)
                {
                        if(itr->second == holder)
                        {
                                mHolders.erase(itr);
                                holderLock.Release();
                                return;
                        }
                }
                holderLock.Release();
        }

protected:
        HolderMap mHolders;
        Mutex holderLock;
};

#define sEventMgr EventMgr::getSingleton()

这里类把事件操作封装起来,把事件对象,事件参数 处理函数 事件钩子,事件场景所有的都联系起来。

23

主题

59

帖子

59

积分

注册会员

Rank: 2

积分
59
发表于 2010-4-20 21:00:00 | 显示全部楼层

Re:最近突然感觉自己很强。

180

主题

3511

帖子

3520

积分

论坛元老

Rank: 8Rank: 8

积分
3520
发表于 2010-4-21 00:14:00 | 显示全部楼层

Re:最近突然感觉自己很强。

你能不能用100行代码来实现以上所有功能?

0

主题

11

帖子

28

积分

注册会员

Rank: 2

积分
28
发表于 2010-4-21 12:02:00 | 显示全部楼层

Re:最近突然感觉自己很强。

楼主场景的处理,是我关注的重点,顶!

13

主题

312

帖子

312

积分

中级会员

Rank: 3Rank: 3

积分
312
发表于 2010-4-21 17:49:00 | 显示全部楼层

Re: Re:最近突然感觉自己很强。

jioudaotian: Re:最近突然感觉自己很强。

楼主场景的处理,是我关注的重点,顶!

我也很想学习一下!能详细说说么?

---------------------------------------------------------------------

开源图形处理器体系结构论坛(OpenGPU论坛)  
http://www.opengpu.org/bbs/

OpenGPU Graphics Open Source community图形开源社区),聚焦领域(focus domain)包括:
  * GPU Architecture图形处理器体系结构).
  * Graphics Algorithm图形算法).
  * Open Source Rendering Engine开源渲染器).
  * Open Source GPU Simulator/RTL Implement开源GPU模拟器).
  * GPGPU Programming 面向通用的图形处理器编程
  * GPU General-purposed ComputingGPU通用计算).
.


2

主题

7

帖子

9

积分

新手上路

Rank: 1

积分
9
发表于 2010-12-27 11:45:00 | 显示全部楼层

Re:最近突然感觉自己很强。

看了楼主的文章。
说点感受:
让我想起了这样的代码注释:
if ( nBytes > 0) // 如果字节数大于0

楼主的解释基本上没有自己的理解,对代码做了一个大概中文翻译罢了。

0

主题

7

帖子

7

积分

新手上路

Rank: 1

积分
7
发表于 2010-12-30 18:03:00 | 显示全部楼层

Re: 最近突然感觉自己很强。

恕我直言,没看出来亮点  [em13]
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-6-3 06:07

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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