话说用了 Delta3D 能有一段时间了(有一个月了?)项目不用急着完成,结果却是越做越懒。做项目的过程中发现 Delta3d 的系统实在是太庞大了 osg ,ode, cal3d , cegui… 全都堆一起了。再加上以前不是搞图形的,最核心的 部分入门无方,崩溃 ing 。呃 既然本人图形学目前是个白痴,就准备先不具体看 osg 的实现,而是从 delta3d 的整体构架来慢慢学习。顺便用这段时间补一下图形方面的基础知识,从抽象层和底层两头并进。
闲话不多说,一切从源头开始 ---- 大部分 Delta3D 类罪恶的源泉 dtCore::Base
关于 Base 类的分析网上已经有文章了,像我这样抱着学习目的的人也应该都看过了,不过还是先随便说说吧,当是开个头。
dtCore::Base 的部分接口
- class DT_CORE_EXPORT Base : public sigslot::has_slots<>, public osg::Referenced
- {
- DECLARE_MANAGEMENT_LAYER(Base)
- Public:
- struct DT_CORE_EXPORT MessageData
- {
- std::string message;
- Base* sender;
- void* userData;
- };
- virtual void OnMessage(MessageData*) {};
- void AddSender(Base* sender);
- void RemoveSender(Base* sender);
- void SendMessage(const std::string& message = "", void* data = 0);
- private:
- sigslot::signal1<MessageData*> mSendMessage;
- }
从这里可以看出Base继承自sigslot::has_slots<>和osg::Referenced。其中
osg::Referenced 是为了实现 dtCore::RefPtr<T> 这个智能指针所使用的
Sigslot::has_slots<> 实现了最基本的消息机制(这也来源自网上的一个开源项目)
关于智能指针与信号量(委托,消息?反正很多名字)的介绍在网上能找到很多。有时间的可以看一下 Boost 库,那上面的实现简直是太变态了。不过我感觉只是用于内部消息传递, Sigslot 的功能已经足够了。另外注意由于该类继承于osg::Referenced ,于是可以利用 dtCore::RefPtr 这个智能指针访问,看过代码的同学可能会发现 Base 的析构函数是protected 。所以对在堆上的对象 delete 是不行的,只能通过 RefPtr 来干掉他了。
- DECLARE_MANAGEMENT_LAYER(Base)
这是一个宏,在 Delta3d 中的管理级别组件中被大量使用 主要就是为了管理实体而使用的。具体情况看代码吧,每个实例初始化的时候会注册到一个静态的 vector<Base*> 中,然后通过相应接口找到该实体。
- void AddSender(Base* sender); void RemoveSender(Base* sender);
上述两个接口是用来添加和删除该类所接受消息的发送者的。其实就是对 Sigslot 中的 signal 的 connect_slot 和disconnect 的一个封装。
- virtual void OnMessage(MessageData*) {}
通过 AddSender 将 sender 的 SendMessage 与该类的 OnMessage(MessageData *) 连接起来。最后是
- void SendMessage(const std::string& message = "", void* data = 0);
这是一个发送消息的接口。其实在 Base 内部发送的是下列的这个结构体 , 也就是OnMessage(MessageData*)中的参数。
- struct DT_CORE_EXPORT MessageData
- {
- std::string message;
- Base* sender;
- void* userData;
- };
从上面的 OnMessage 中看到了 Delta3D 已经规定了其内部传递机制中只有一个参数,于是乎上面的结构体中使用了 userData 来拓展所能传递的数据。用 message 来判断所传递的消息名称。
OK 关于 dtCore::Base 的介绍也就到这了。没有说太多的细节,有兴趣的可以直接看代码。
最近突然感觉没有体力通宵学习了,郁闷中。万恶的天气,热死我了!