首页 > REDM基础教程 > REDM基础教程20-注册类机制
2018十月20

REDM基础教程20-注册类机制

[隐藏]

其实插件系统和注册机制在REDM文档中都有详细的流程图,因回答过很多次类似的问题,所以这里作二次阐述:

    

1.注册类机制

REDM统一使用了注册类机制,内置的基础功能均使用了这一机制,如下所示:

enum DMREGTYPE
	{
		DMREG_Unknown                           = 0,	///<此类型仅供内部使用
		DMREG_Skin								= 1,    ///<皮肤类,指单张图片的绘制方式,如平铺、拉伸、9宫格
		DMREG_Style                             = 2,	///<样式类
		DMREG_Attribute                         = 3,	///<XML解析类
		DMREG_Window                            = 4,    ///<DUI窗口类
		DMREG_Layout                            = 5,    ///<锚点布局类
		DMREG_ImgDecoder                        = 6,    ///<解码类
		DMREG_Res		                        = 7,    ///<资源打包类
		DMREG_Render                            = 8,    ///<渲染类
		DMREG_Draw                              = 9,    ///<绘制类
		DMREG_Log	                            = 10,    ///<LOG类
		DMREG_FlowLayout                        = 11,   ///<流式布局类,基于DUIWindow实现
		DMREG_ToolTip                           = 12,   ///<tooltip类
		DMREG_Animate                           = 13,   ///<动画注册类
		DMREG_Script                            = 14,   ///<脚本类
		DMREG_Trans                             = 15,   ///<翻译类
		
		DMREG_MAX, 
	};

在DmMain\inc\Modules\DMPluginImpl.cpp的Install函数中注册了所有的内置类:

void DMPluginImpl::Install()
	{
		DMCode iErr = DM_ECODE_OK;
		// 默认Log -----------------------------
                ...
		// 默认解码器 ----------------------------
		...
		// 默认Res -------------------------------
		...
		// 默认Render-----------------------------
		...
		// 默认Draw-----------------------------
		...

		// 默认Skin -----------------------------
		...

		// 默认Style -----------------------------
		...
		// 默认Layout ----------------------------
		...
		// 内置Tooltip ---------------------------
		...

		// 内置Trans ---------------------------
		...

		// 内置Widget ----------------------------
		...

		// 内置FlowLayout ----------------------------
		iErr = g_pDMApp->Register(DMRegHelperT<DUIVLayout>(),true);
		......
	}

    

1.1.注册类机制好处

    

1.允许你在外部重写类来覆盖内部的类。

   

例如内置的DUIButton.h,它的类定义了以下宏:

DMDECLARE_CLASS_NAME(DUIButton,L"Button",DMREG_Window);

DMREG_Window表示是DMREGTYPE类型,这里是指控件集合。

而"Button"关键字表示一种特定的DUI控件,它也是xml的唯一标识(不区分大小写),我们的xml是这样写的:

<button pos="......"/>

在解析xml时会自动针对此行xml生成一个DUIButton的类实例对象。

  

对于重写类,它们和内置的类一样,都需要实现以下宏定义:

DMDECLARE_CLASS_NAME(theclass, classname, classtype) 

    

假定外部定义了一个class,它的类名可能叫A,B,C,我们就假定它是A:

class A : public xxx
{
    DMDECLARE_CLASS_NAME(A,L"Button",DMREG_Window);
}

然后调用:

iErr = g_pDMApp->Register(DMRegHelperT<A>(),true);

注意最后一个参数为true,表示强制替换。

这时内部在解析xml时会自动针对上行xml生成一个A的类实例对象。而不再是DUIButton的类实例对象。

    

2.允许你外部加入新的类,并把它设置为默认调用。

在DMDesigner工程的Plugin.cpp中,你可以找到如下代码:

void Plugin::Install()
{
	g_pDMApp->Register(DMRegHelperT<Layout>(),true);
	...
	g_pDMApp->SetDefRegObj(Layout::GetClassName(),Layout::GetClassType());
}
==》
DMDECLARE_CLASS_NAME(Layout,L"Layout",DMREG_Layout);

表示对布局(DMREG_Layout)做了重载,因为DMMain内置的是:

DMDECLARE_CLASS_NAME(DMLayoutImpl,L"DMLayoutImpl",DMREG_Layout);

"Layout"和"DMLayoutImpl"是不同的关键字,所以Layout并没有直接覆盖内置的DMLayoutImpl,而是通过

g_pDMApp->SetDefRegObj(Layout::GetClassName(),Layout::GetClassType());

把它设置为默认调用。

  

同样搜索SetDefRegObj关键字你还能发现:

g_pDMApp->SetDefRegObj(ResMultFolder::GetClassName(),ResMultFolder::GetClassType());// 默认使用Res多文件夹方式
g_pDMApp->SetDefRegObj(DMResZipImpl::GetClassName(),DMResZipImpl::GetClassType());// 默认使用Res的zip方式
g_pDMApp->SetDefRegObj(DMResMultZipImpl::GetClassName(),DMResMultZipImpl::GetClassType());// 默认使用Res的多个zip方式
g_pDMApp->SetDefRegObj(DMSkiaRenderImpl::GetClassName(),DMSkiaRenderImpl::GetClassType());// 默认使用Skia绘制引擎

 

tips类型比较特殊,比如QQDemo和DMDesigner中各实现了一个:

DMDECLARE_CLASS_NAME(DMTipsImpl,L"DMTipsImpl",DMREG_ToolTip);
DMDECLARE_CLASS_NAME(TipsImpl,L"TipsImpl",DMREG_ToolTip);

它的使用方式为xml中配置:

<dm  regtip="DMTipsImpl" ....>

也就是我们可以针对不同的DM主窗口使用不同的tips效果类

   

3.允许你加入新的控件

这个在1的基础上应该比较好理解,比如实现了一个DUI控件B并注册

class B : public xxx
{
    DMDECLARE_CLASS_NAME(B,L"cc",DMREG_Window);
}
g_pDMApp->Register(DMRegHelperT<B>(),true);

它的使用方式为xml中配置:

<cc pos="..."/>

 18.gif19.gif

    

    

1.2.注册类机制原理

  

IDMReg通过DMRegHelperT模板来辅助注册。

IDMReg通过DMRegHelperT模板来辅助注册。

IDMReg对象提供了 创建注册类实例对象、取得注册类名、取得注册父类名、提供注册类型Type等封装接口。

例如:

image.png

image.png


IDMReg对象是通过注册类名这个字符串来标识是否相同的, 注册类名是用户自定义的一个标识字符串,不一定是真实的类名。

比如:对于DUIButton这个类,内部用L“Button”来标识注册类名,而不是L“DUIButton”

   

   

 DMRegTypeItem管理了同一type的IDMReg

image.png

         


 DMRegMgr对每个Type维护一个DMRegTypeItem提供Register注册接口和CreateRegObj创建对象接口

image.png

   

    

  

下一节:REDM基础教程21-插件机制









文章作者:hgy413
本文地址:http://hgy413.com/5302.html
版权所有 © 转载时必须以链接形式注明作者和原始出处!

本文的评论功能被关闭了.