123
This commit is contained in:
297
Editor/PluginManager.cpp
Normal file
297
Editor/PluginManager.cpp
Normal file
@@ -0,0 +1,297 @@
|
||||
// PluginManager.cpp: implementation of the CPluginManager class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "PluginManager.h"
|
||||
|
||||
#include <io.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
CPluginManager::CPluginManager()
|
||||
{
|
||||
m_pIAssociatedPlugin = NULL;
|
||||
m_iAssociatedPluginUIID = 0;
|
||||
}
|
||||
|
||||
CPluginManager::~CPluginManager()
|
||||
{
|
||||
CleanUp();
|
||||
}
|
||||
|
||||
bool CPluginManager::LoadAllPlugins(CString strPath)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Load all plugin DLLs which are in the passed path
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CFileEnum cDLLFiles;
|
||||
__finddata64_t sFile;
|
||||
char szFilePath[_MAX_PATH];
|
||||
HMODULE hPlugin = NULL;
|
||||
pfnCreatePluginInstance pfnFactory = NULL;
|
||||
PLUGIN_INIT_PARAM sInitParam = { GetIEditor(), NULL /*TODO: CEngineSingleton::GetGameInterface()*/ };
|
||||
IPlugin *pIPlugin = NULL;
|
||||
bool bReturn;
|
||||
uint8 iUIID = 0;
|
||||
|
||||
// Terminate old plugins first
|
||||
CleanUp();
|
||||
|
||||
CLogFile::WriteLine("Loading plugins...");
|
||||
|
||||
if (!PathFileExists(strPath.GetBuffer(0)))
|
||||
{
|
||||
CLogFile::FormatLine("Can't find plugin directory '%s'", strPath.GetBuffer(1));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cDLLFiles.StartEnumeration(strPath.GetBuffer(1), "*.DLL", &sFile))
|
||||
{
|
||||
do
|
||||
{
|
||||
// Construct the full filepath of the current file
|
||||
strcpy(szFilePath, strPath.GetBuffer(0));
|
||||
PathAddBackslash(szFilePath);
|
||||
strcat(szFilePath, sFile.name);
|
||||
|
||||
// Load the plugin's DLL
|
||||
hPlugin = LoadLibrary(szFilePath);
|
||||
|
||||
if (!hPlugin)
|
||||
{
|
||||
CLogFile::FormatLine("Can't load plugin DLL '%s' !", szFilePath);
|
||||
ASSERT(hPlugin);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Query the factory pointer
|
||||
pfnFactory = (pfnCreatePluginInstance) GetProcAddress(hPlugin, "CreatePluginInstance");
|
||||
|
||||
if (!pfnFactory)
|
||||
{
|
||||
CLogFile::WriteLine("Can't query plugin DLL factory pointer !");
|
||||
ASSERT(pfnFactory);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create an instance of the plugin
|
||||
pIPlugin = pfnFactory(&sInitParam);
|
||||
|
||||
if (!pIPlugin)
|
||||
{
|
||||
CLogFile::FormatLine("Can't create instance of plugin DLL '%s' !", szFilePath);
|
||||
ASSERT(pfnFactory);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Push the plugin on the list
|
||||
m_lPlugins.push_back(pIPlugin);
|
||||
|
||||
// Temporary associate the editor interface with the current plugin. This ensures
|
||||
// that all calls from to it are associated with it
|
||||
// We need a special user inteface ID for the plugin which is stored with all created
|
||||
// UI elements. This allows us later to easly identify the plugin which handles events
|
||||
// of the UI element
|
||||
SetAssociatedPlugin(pIPlugin,iUIID);
|
||||
|
||||
// Ask the plugin to create its user interface now
|
||||
bReturn = pIPlugin->CreateUIElements();
|
||||
|
||||
if (!bReturn)
|
||||
{
|
||||
CLogFile::WriteLine("Plugin failed to create UI elements !");
|
||||
ASSERT(bReturn);
|
||||
continue;
|
||||
}
|
||||
|
||||
// No plugin is associated with the interface now, this helps to catch errors where
|
||||
// plugins access the UI creation function of the editor interface outside of
|
||||
// CreateUIElements()
|
||||
SetAssociatedPlugin(NULL,0);
|
||||
|
||||
// Store the UI ID - Plugin association in the map
|
||||
m_mUIIDPluginMap[iUIID] = pIPlugin;
|
||||
|
||||
// Next UIID
|
||||
iUIID++;
|
||||
|
||||
if (iUIID == 0)
|
||||
{
|
||||
CLogFile::WriteLine("Too many plugins loaded, 256 maximum !");
|
||||
AfxMessageBox("Too many plugins loaded, 256 maximum !");
|
||||
ASSERT(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Write log string about plugin
|
||||
CLogFile::FormatLine("Successfully loaded plugin '%s' version '%i' (GUID: %s)",
|
||||
pIPlugin->GetPluginName(), pIPlugin->GetPluginVersion(), pIPlugin->GetPluginGUID());
|
||||
|
||||
} while (cDLLFiles.GetNextFile(&sFile));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPluginManager::CleanUp()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Unloads all plugins without asking for unsaved data etc.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
PluginIt it;
|
||||
|
||||
CLogFile::WriteLine("Unloading all previous plugins");
|
||||
|
||||
// Release the plugins
|
||||
for (it=m_lPlugins.begin(); it!=m_lPlugins.end(); it++)
|
||||
(* it)->Release();
|
||||
|
||||
// Clear the list of plugins
|
||||
m_lPlugins.clear();
|
||||
|
||||
// Clear the map of plugin event maps
|
||||
m_mPluginEventMap.clear();
|
||||
|
||||
// Clear the map of UI IDs and plugins
|
||||
m_mUIIDPluginMap.clear();
|
||||
}
|
||||
|
||||
void CPluginManager::NewDocument()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Resets the status of all plugins to be prepared for a document
|
||||
// change
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
PluginIt it;
|
||||
|
||||
CLogFile::WriteLine("Resetting the state of all plugins");
|
||||
|
||||
for (it=m_lPlugins.begin(); it!=m_lPlugins.end(); it++)
|
||||
(* it)->ResetContent();
|
||||
}
|
||||
|
||||
IPlugin * CPluginManager::GetPluginByGUID(const char * pszGUID)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Try to find a plugin which the passed GUID
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
PluginIt it;
|
||||
|
||||
for (it=m_lPlugins.begin(); it!=m_lPlugins.end(); it++)
|
||||
{
|
||||
if (strcmp((* it)->GetPluginGUID(), pszGUID) == 0)
|
||||
return (* it);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IPlugin * CPluginManager::GetPluginByUIID(uint8 iUserInterfaceID)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Try to find the plugin which has the passed user interface ID
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
UIIDPluginIt it;
|
||||
|
||||
// Look up the plugin pointer from the list
|
||||
it = m_mUIIDPluginMap.find(iUserInterfaceID);
|
||||
|
||||
// Found ?
|
||||
if (it == m_mUIIDPluginMap.end())
|
||||
return NULL;
|
||||
|
||||
return (* it).second;
|
||||
}
|
||||
|
||||
IUIEvent * CPluginManager::GetEventByIDAndPluginID(uint8 iPluginID, uint8 iEvtID)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Return the event interface of a user interface element which is
|
||||
// specified by its ID and the user interface ID of the plugin which
|
||||
// created the UI element
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
IPlugin * pIPlugin = NULL;
|
||||
EventHandlerIt EventIt;
|
||||
PluginEventIt PluginIt;
|
||||
|
||||
// Try to get the plugin pointer
|
||||
pIPlugin = GetPluginByUIID(iPluginID);
|
||||
|
||||
// Failed ?
|
||||
if (!pIPlugin)
|
||||
return NULL;
|
||||
|
||||
// Try to get the event map for the plugin
|
||||
PluginIt = m_mPluginEventMap.find(pIPlugin);
|
||||
|
||||
// Failed ?
|
||||
if (PluginIt == m_mPluginEventMap.end())
|
||||
return NULL;
|
||||
|
||||
// Try to get the event handler for the passed event ID
|
||||
EventIt = (* PluginIt).second.find(iEvtID);
|
||||
|
||||
// Failed ?
|
||||
if (EventIt == (* PluginIt).second.end())
|
||||
return NULL;
|
||||
|
||||
return (* EventIt).second;
|
||||
}
|
||||
|
||||
bool CPluginManager::CanAllPluginsExitNow()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Calls the CanExitNow() function of all plugins
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
PluginIt it;
|
||||
|
||||
for (it=m_lPlugins.begin(); it!=m_lPlugins.end(); it++)
|
||||
{
|
||||
if (!(* it)->CanExitNow())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPluginManager::CallExport(const char * pszGamePath)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Call the export function for all plugins
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
PluginIt it;
|
||||
|
||||
for (it=m_lPlugins.begin(); it!=m_lPlugins.end(); it++)
|
||||
{
|
||||
if (!(* it)->ExportDataToGame(pszGamePath))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPluginManager::AddHandlerForCmdID(IPlugin *pIPluginOfHandler, uint8 iCmdID, IUIEvent *pIEvt)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Associates the UI element ID dwCmdID of the plugin
|
||||
// pIPluginOfHandler with the event handler pIEvt
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
(m_mPluginEventMap[pIPluginOfHandler])[iCmdID] = pIEvt;
|
||||
}
|
||||
|
||||
void CPluginManager::SetAssociatedPlugin(IPlugin * pIPlugin,uint8 iUIID)
|
||||
{
|
||||
m_pIAssociatedPlugin = pIPlugin;
|
||||
m_iAssociatedPluginUIID = iUIID;
|
||||
};
|
||||
Reference in New Issue
Block a user