www.pudn.com > zfxcengine-0.1.0.zip > ceDynlib.cpp


/* $Id: ceDynlib.cpp,v 1.16 2005/08/24 13:35:15 andreaskohn Exp $ */ 
//////////////////////////////////////////////////////////////////////////////// 
//  Module:     Core 
//! @file:      ceDynLib.cpp 
//  Created:    06.08.2003 
//  Author:     Martin Zielinski 
// 
//////////////////////////////////////////////////////////////////////////////// 
#include  
#include  
using namespace std; 
 
#include "SDL.h" 
#include "SDL_loadso.h" 
 
#include "Core/ceExceptions.h" 
#include "Core/ceDebug.h" 
#include "Core/ceDynlib.h" 
#include "Core/ceIDefaultSystem.h" 
 
#include "Core/ceMemManager.h" 
namespace ZFXCE { 
namespace DynLib { 
	typedef void (*CREATESYSTEM)  (ceIDefaultSystem** System); 
	typedef void (*RELEASESYSTEM) (ceIDefaultSystem** System); 
 
	////////////////////////////////////////////////////////////////////////////////// 
	//! \brief Descriping data structure for library handle 
	////////////////////////////////////////////////////////////////////////////////// 
	struct LibHandle  
	{ 
		ceModule Mod;				//! Module enumerator (for ZFXCE specific modules) 
		std::string RefName;		//! Reference name 
		std::string LibName;		//! Library name 
		void* SDLHandle;			//! Pointer to SDL handle 
		CREATESYSTEM CreateFnc;		//! Function pointer to creator of module 
		RELEASESYSTEM ReleaseFnc;	//! Function pointer to releaser of module 
		ceIDefaultSystem *m_pSystem;//! Pointer to createt instance of loaded module 
 
		//! \brief Default constructor for a created libhandle instance 
		LibHandle(){ 
			Mod = CE_UNKNOWN; 
			RefName = ""; 
			LibName = ""; 
			m_pSystem = NULL; 
		} 
	}; 
		 
	////////////////////////////////////////////////////////////////////////////////// 
	std::vector LibHandles; 
		 
	////////////////////////////////////////////////////////////////////////////////// 
	void RegisterDynLinkedLib(std::string DLLName, std::string ReferenceName) 
	{ 
		PUSH_FUNCTION; 
	 
		struct LibHandle handle; 
		handle.RefName = ReferenceName; 
		handle.LibName = DLLName; 
		handle.SDLHandle = SDL_LoadObject(handle.LibName.c_str() ); 
 
		if (NULL == handle.SDLHandle) { 
			std::string error = "Konnte diese Lib nicht laden: "; 
			error += DLLName + "\n"; 
			error += "Fehlermeldung: "; 
			error += SDL_GetError(); 
			error += "\n"; 
			CE_EXCEPTION(error, CELS_ERROR); 
		} 
 
		handle.CreateFnc = (CREATESYSTEM) SDL_LoadFunction(handle.SDLHandle, "CreateSystem"); 
		handle.ReleaseFnc = (RELEASESYSTEM) SDL_LoadFunction(handle.SDLHandle, "ReleaseSystem"); 
		if (NULL == handle.CreateFnc) { 
			std::string error = "Konnte diese Funktion aus der Lib nicht laden: "; 
			error += DLLName + "\n"; 
			error += "CreateSystem() \n"; 
			error += "Fehlermeldung: "; 
			error += SDL_GetError(); 
			error += "\n"; 
			CE_EXCEPTION(error, CELS_ERROR); 
		} 
 
		// Enshure existing releaser 
		if (NULL == handle.ReleaseFnc) { 
			std::string error = "Konnte diese Funktion aus der Lib nicht laden: "; 
			error += DLLName + "\n"; 
			error += "ReleaseSystem() \n"; 
			error += "Fehlermeldung: "; 
			error += SDL_GetError(); 
			error += "\n"; 
			CE_EXCEPTION(error, CELS_ERROR); 
		} 
 
		LibHandles.push_back(handle); 
	} 
	////////////////////////////////////////////////////////////////////////////////// 
	void RegisterDynLinkedLib(const ceModule Module) 
	{ 
		PUSH_FUNCTION; 
			 
		ce_assert (CE_UNKNOWN != Module); 
		RegisterDynLinkedLib(MOD_NAME[Module], MOD_NAME[Module]); 
	} 
	////////////////////////////////////////////////////////////////////////////////// 
	void GetFromDLL(std::string ReferenceName, ceIDefaultSystem** System) 
	{ 
		PUSH_FUNCTION; 
			 
		for (UINT i=0; i < LibHandles.size(); i++) { 
			LibHandle handle = LibHandles[i]; 
			if (ReferenceName == handle.RefName) { 
				handle.CreateFnc(System); 
				handle.m_pSystem = *System; 
				return; 
			} 
		} 
		*System = NULL; 
			 
		return; 
	} 
	////////////////////////////////////////////////////////////////////////////////// 
	bool GetLoadedSystem(const ceModule Module, ceIDefaultSystem **pSystem) 
	{ 
		PUSH_FUNCTION; 
 
		std::vector::iterator it; 
		for (it = LibHandles.begin(); it != LibHandles.end(); ++it) { 
			if ((*it).Mod == Module) { 
				*pSystem = (*it).m_pSystem; 
				return true; 
			} 
		} 
		return false; 
	} 
	////////////////////////////////////////////////////////////////////////////////// 
	bool GetLoadedSystem(const std::string &strName, ceIDefaultSystem **pSystem) 
	{ 
		PUSH_FUNCTION; 
	 
		std::vector::iterator it; 
		for (it = LibHandles.begin(); it != LibHandles.end(); ++it) { 
			if ((*it).LibName == strName) { 
				*pSystem = (*it).m_pSystem; 
				return true; 
			} 
		} 
		return false; 
	} 
	////////////////////////////////////////////////////////////////////////////////// 
	////////////////////////////////////////////////////////////////////////////////// 
		void GetFromDLL(const ceModule Module, ceIDefaultSystem** System) 
		{ 
			PUSH_FUNCTION; 
 
			assert (CE_UNKNOWN != Module); 
			GetFromDLL(MOD_NAME[Module], System); 
		} 
		////////////////////////////////////////////////////////////////////////////////// 
		void DestroySystem(std::string ReferenceName, ceIDefaultSystem** System) 
		{ 
			PUSH_FUNCTION; 
			 
			assert (NULL != *System); 
			std::vector::iterator it; 
			for (it = LibHandles.begin(); it!=LibHandles.end(); it++) { 
				LibHandle handle = *it; 
				if (ReferenceName == handle.RefName) { 
					handle.ReleaseFnc(System); 
					handle.m_pSystem = NULL; 
					System = NULL; 
					return; 
				} 
			} 
		} 
		////////////////////////////////////////////////////////////////////////////////// 
		void DestroySystem(ceIDefaultSystem** ppSystem) 
		{ 
			ce_assert (NULL != ppSystem); 
			// XXX const ceModule Module = (*ppSystem)->GetModuleDesc(); 
			// XXX DestroySystem(MOD_NAME[Module], ppSystem); 
		} 
		////////////////////////////////////////////////////////////////////////////////// 
		ceModule TranslateSysName(const std::string &strSysName) 
		{ 
			PUSH_FUNCTION; 
 
			ceModule Module = CE_UNKNOWN; 
			std::vector::iterator it; 
			for (it = LibHandles.begin(); it != LibHandles.end(); ++it) { 
				if ((*it).LibName == strSysName) { 
					Module = (*it).Mod; 
					break; 
				} 
		} 
 
		return Module; 
	} 
	////////////////////////////////////////////////////////////////////////////////// 
}	// namespace DynLib 
} // ZFXCE namespace