基于PluginSDK的模块下沉和回调函数封装设计

一、Plugin SDK模块下沉的两种设计

在大型项目中,框架通常是支持插件加载和插件开发的,这样有助于提升程序的效率和完成更多的第三方的开发需求;因此,在实际场景中,也经常会出现对已有的模块进行下沉,下面给出了两种常用的设计:

1)已有Module基于Core层的封装

这样情况是工程中的Module都基于Core lib 进行封装,封装成PluginSDK 所支持的形式;数据层Module中用的参数,返回值都是Core层所提供的;

2)已有Module基于现有PluginSDK层的封装

这样情况是工程中的Module都基于PluginSDK 进行封装,外部的话可以直接调用;数据层Module中用的参数,返回值都是Plugin SDK层所提供的;

区别:

1)第一种是Module 是直接调用Core 代码,效率高,比较直观好理解;第二种是间接调用,效率会低些,比较抽象点,在某些特殊的场合跨品台性更好,如Web上的一个插件要模仿Win上面来进行实现;

2)第一种负责PluginSDK的人员在封装上可能要多一些;第二种Module在封装的时候已经采用了PluginSDK的数据类型,因此做的封装要少些;

 

二、基于PluginSDK回调函数设计

基于PluginSDK的回调函数设计和一般的数据类型封装是同样的道理,在我们的PluginSDK都需要对框架的程序数据做一个封装,不同于一般的数据类型或者是指针类型取了一个别名,这里需要对框架中的接口类型进行封装即封装成系列的函数指针,下面给出了简单的示意图:

设计示例代码

//主框架中的接口,框架程序进行管理,在特定的条件下触发   
class IReader_UserMessagehandler
{
public:
	virtual				~IReader_UserMessagehandler() {}
	virtual bool		OnUserMessageData(void *pData) { return false; }
};

//PluginSDK的部分
class CFR_ReaderUserMessageHandler : public IReader_UserMessagehandler
{
public:
	CFR_ReaderUserMessageHandler(FR_ReaderUserMessageHandlerCallbacks callbacks)
	{
		memset(&m_callbacks, 0, sizeof(FR_ReaderUserMessageHandlerCallbacksRec));
		memcpy(&m_callbacks, callbacks, callbacks->lStructSize);
		if (callbacks->lStructSize < sizeof(FR_ReaderUserMessageHandlerCallbacksRec))
		{
			BYTE * pAttress = (BYTE *)&m_callbacks;
			memset(pAttress + callbacks->lStructSize, 0, sizeof(FR_ReaderUserMessageHandlerCallbacksRec) - callbacks->lStructSize);//set new create method to 0.
		}
	}
	virtual ~CFR_ReaderUserMessageHandler() {}

	virtual bool		OnUserMessageData(void *pData)
	{
		if (m_callbacks.FROnUserMessageData)
		{
			return m_callbacks.FROnUserMessageData(m_callbacks.clientData, pData);
		}
		return false;
	}

private:
	FR_ReaderUserMessageHandlerCallbacksRec m_callbacks;
};

/
class CFR_ReaderUserMessageHandler_V14 //Internal use
{
public:
	static FR_ReaderUserMessageHandler New(FR_ReaderUserMessageHandlerCallbacks callbacks);
	static void Destroy(FR_ReaderUserMessageHandler handler);
};

CFR_ReaderUserMessageHandler_V14::New(FR_ReaderUserMessageHandlerCallbacks callbacks)
{
	return (FR_ReaderUserMessageHandler)FX_NEW CFR_ReaderUserMessageHandler(callbacks);
}

void CFR_ReaderUserMessageHandler_V14::Destroy(FR_ReaderUserMessageHandler handler)
{
	CFR_ReaderUserMessageHandler* pHander = (CFR_ReaderUserMessageHandler*)handler;
	delete pHander;
}


/
//框架的实现
class CFR_App_V1
{
public:
	static FS_BOOL  RegisterUserMessageHanler(FR_ReaderUserMessageHandler handler);

	static FS_BOOL  UnRegisterUserMessageHanler(FR_ReaderUserMessageHandler handler);
};

FS_BOOL  CFR_App_V1::RegisterUserMessageHanler(FR_ReaderUserMessageHandler handler)
{
	return g_pReaderAppEx->RegisterUserMessageHanler((CFR_ReaderUserMessageHandler*)handler);
}

FS_BOOL  CFR_App_V1::UnRegisterUserMessageHanler(FR_ReaderUserMessageHandler handler)
{
	return g_pReaderAppEx->UnRegisterUserMessageHanler((CFR_ReaderUserMessageHandler*)handler);
}


typedef struct _fr_ReaderUserMessageHandler_callbacks_
{
	unsigned long lStructSize;

	/** The user-supplied data. */
    //能够传递一些特殊的信息,如Value或者String,来表明当前注册对象的一些参数、特征等
 //或者起到一种标识作用相当于一种唯一ID;也可以理解为一种保留字,暂不使用;
	FS_LPVOID		clientData;

	FS_BOOL(*FROnUserMessageData)(FS_LPVOID clientData, FS_LPVOID pData);
}FR_ReaderUserMessageHandlerCallbacksRec, *FR_ReaderUserMessageHandlerCallbacks;

//*主框架提供了New和Destroy的接口,数据的分配与记录是框架完成的,插件只是申请和释放*

/
//主程序再提供一个注册和撤销的接口,以供不同的插件使用

INTERFACE(FS_BOOL, FRAppRegisterUserMessageHanler, (FR_ReaderUserMessageHandler handler))

INTERFACE(FS_BOOL, FRAppUnRegisterUserMessageHanler, (FR_ReaderUserMessageHandler handler))





注意上面的clientData参数:能够传递一些特殊的信息,如Value或者String,来表明当前注册对象的一些参数、特征等;或者起到一种标识作用相当于一种唯一ID;也可以理解为一种保留字,暂不使用;

调用示例代码

//CDocEventHandler.h
class CDocEventHandler
{
public:
	static void RegisterEventHandler(FS_LPVOID clientData);
protected:
	static void OnDocPermChange(FS_LPVOID clientData, FR_Document frDoc);
	static void OnDocCurrentWndProvideChange(FS_LPVOID clientData, FR_Document frDoc,FS_ByteString fbsWndProvideName);
	static void OnDocPageLabelChange(FS_LPVOID clientData, FR_Document frDoc);
protected:
	CDocEventHandler() { ; }
	~CDocEventHandler() { ; }
	
	static FR_DocEventCallbacksRec m_frCallbacks;
};



//CDocEventHandler.cpp
FR_DocEventCallbacksRec CDocEventHandler::m_frCallbacks = { 0 };
void CDocEventHandler::RegisterEventHandler(FS_LPVOID clientData)
{
	m_frCallbacks.lStructSize = sizeof(FR_DocEventCallbacksRec);
	m_frCallbacks.clientData = clientData;

	m_frCallbacks.FRDocOnPermissionChange = OnDocPermChange;
	m_frCallbacks.FROnDocCurrentWndProvideChange = OnDocCurrentWndProvideChange;
	m_frCallbacks.FROnDocPageLabelChange = OnDocPageLabelChange;

	FRAppRegisterDocHandlerOfPDDoc(&m_frCallbacks);
}

//GlobalHandler.cpp实际的调用 
void CGlobalHandler::Initialize(HINSTANCE dllInstance)
{
	assert(dllInstance);
        //.....
	CDocEventHandler::RegisterEventHandler(nullptr);
	//.....
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Maya的C++ API提供了一种使用C++编写插件和扩展的方式,可以更高效地操作和控制Maya场景。其中一个常见的应用是使用C++编写场景回调函数。 场景回调函数是在Maya场景中发生特定事件时被调用的函数。通过注册回调函数,您可以在场景中的对象创建、删除、修改等事件发生时执行自定义的操作。 以下是一个示例,演示如何使用C++编写并注册一个场景回调函数: ```cpp #include <maya/MFnPlugin.h> #include <maya/MSceneMessage.h> // 定义回调函数 void mySceneCallback(MSceneMessage::SceneMessageType messageType, void* clientData) { // 在这里执行自定义操作 // 根据messageType判断发生的事件类型,并根据需要执行相应的操作 } MStatus initializePlugin(MObject obj) { MFnPlugin plugin(obj, "Your Name", "1.0", "Any"); // 注册回调函数 MCallbackId callbackId = MSceneMessage::addCallback(MSceneMessage::kAfterCreate, mySceneCallback); return MS::kSuccess; } MStatus uninitializePlugin(MObject obj) { MFnPlugin plugin(obj); // 移除回调函数 MSceneMessage::removeCallback(callbackId); return MS::kSuccess; } ``` 在上述示例中,`mySceneCallback`函数是自定义的回调函数,它将在场景中的对象创建后被调用。您可以根据需要修改回调函数的内容和事件类型。 要使用此插件,您需要将其编译为共享库,并将其加载到Maya中。加载插件后,每当场景中有对象创建时,`mySceneCallback`函数将被调用。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值