GS in DLL

    Because static lib (slowlib.base) link slowlib.D3D11, for DLL, slowlib.D3D11 must link slowlib.base

    Remove linking in slowlib.base (just add ifdef endif)

    #ifdef SL_LIB_STATIC
    slGS* SL_API slGSD3D11_create();
    SL_LINK_LIBRARY("slowlib.d3d11");
    #endif
    

    In slowlib.d3d11.cpp I add SL_LIB_EXPORT before #include "slowlib.h", it must be only in one file, because I need to export some functions, and want to use SL_API, and SL_API will import functions in other places.

    #ifndef SL_LIB_STATIC
    #define SL_LIB_EXPORT
    #endif
    

    Import slowlib.base

    #ifndef SL_LIB_STATIC
    SL_LINK_LIBRARY("slowlib.base");
    #endif
    

    All slowlib DLLs will export functions for creating objects of Interface classes. One DLL can have GS, image loader, mesh loader at the same time. For GS name for function will be slSummonGS, all GS DLLs must have this function.

    extern "C"
    {
    #ifdef SL_LIB_STATIC
    	SL_API slGS* SL_CDECL slGSD3D11_create()
    	{
    		slGSD3D11* gs = slCreate<slGSD3D11>();
    		return gs;
    	}
    #else
    	SL_API slGS* SL_CDECL slSummonGS()
    	{
    		slGSD3D11* gs = slCreate<slGSD3D11>();
    		return gs;
    	}
    #endif
    }
    

    And thats all.

    Now I need to scan folder with app and find all .dlls.

    In slFrameworkImpl.h I add

    in slFrameworkImpl class

    slString m_appPath;
    

    I need to get path where app located. In slFramework::Start

    #ifdef SL_PLATFORM_WINDOWS
    		wchar_t pth[1000];
    		GetModuleFileName(0, pth, 1000);
    		g_framework->m_appPath = pth;
    		g_framework->m_appPath.pop_back_before(U'\\');
    #else
    #error OMG
    #endif
    

    Load DLLs

    I need to scan directory. Include filesystem.

    #include <filesystem>
    

    Scan folders. In slFramework::Start

    #ifndef SL_LIB_STATIC
    slStringA utf8apppath;
    g_framework->m_appPath.to_utf8(utf8apppath);
    for (auto& entry : std::filesystem::directory_iterator(utf8apppath.m_data))
    {
    	auto path = entry.path();
    	if (path.has_extension())
    	{
    		auto ex = path.extension();
    		if (ex == ".dll" || ex == ".DLL")
    		{
    			slLog::PrintInfo("[%s]\n", path.generic_string().c_str());
    			LoadLib(path);
    		}
    	}
    }
    #endif
    

    Write LoadLib()

    #ifndef SL_LIB_STATIC
    void LoadLib(std::filesystem::path p)
    {
    	std::string path = p.generic_string();
    	slDLLHandle dll_handle = slDLL::load(path.c_str());
    	if (dll_handle)
    	{
    		bool isGood = false;
    
    		slSummonGS_t f_summon_gs = (slSummonGS_t)slDLL::get_proc(dll_handle, "slSummonGS");
    		if (f_summon_gs)
    		{
    			slGS* gs = f_summon_gs();
    			if (gs)
    			{
    				g_framework->m_gss.push_back(gs);
    				isGood = true;
    			}
    		}
    
    		if (isGood)
    			g_framework->m_dlls.push_back(dll_handle);
    		else
    			slDLL::free(dll_handle);
    	}
    }
    #endif
    

    If DLL has slSummonGS then call it and save pointer to new slGS and save dll_handle

    Free library.

    void slFrameworkImpl::OnDestroy()
    {
    	if (g_framework->m_gss.size())
    	{
    		for (auto o : g_framework->m_gss)
    		{
    			o->Shutdown();
    			slDestroy(o);
    		}
    		g_framework->m_gss.clear();
    	}
    	if (g_framework->m_dlls.size())
    	{
    		for (auto o : g_framework->m_dlls)
    		{
    			slDLL::free(o);
    		}
    		g_framework->m_dlls.clear();
    	}
    }
    

    I need to add new method in GS.

    virtual void Shutdown() = 0;
    

    So, behavior must be like this:

    User call Init, then he probably want to change GS, and he call gs->Shutdown(), not slDestroy(gs).

    I need to have all gs pointers, they will be created when program start.

    Implementation

    #define SLD3DSAFE_RELEASE(x) if(x){x->Release();x=0;}
    
    slGSD3D11::~slGSD3D11()
    {
    	Shutdown();
    }
    
    void slGSD3D11::Shutdown()
    {
    	SLD3DSAFE_RELEASE(m_depthStencilView);
    	SLD3DSAFE_RELEASE(m_blendStateAlphaDisabled);
    	SLD3DSAFE_RELEASE(m_blendStateAlphaEnabled);
    	SLD3DSAFE_RELEASE(m_RasterizerWireframeNoBackFaceCulling);
    	SLD3DSAFE_RELEASE(m_RasterizerWireframe);
    	SLD3DSAFE_RELEASE(m_RasterizerSolidNoBackFaceCulling);
    	SLD3DSAFE_RELEASE(m_RasterizerSolid);
    	SLD3DSAFE_RELEASE(m_depthStencilStateDisabled);
    	SLD3DSAFE_RELEASE(m_depthStencilStateEnabled);
    	SLD3DSAFE_RELEASE(m_depthStencilBuffer);
    	SLD3DSAFE_RELEASE(m_MainTargetView);
    	SLD3DSAFE_RELEASE(m_d3d11DevCon);
    	SLD3DSAFE_RELEASE(m_SwapChain);
    	SLD3DSAFE_RELEASE(m_d3d11Device);
    }
    

    Now I need to implement old methods from slFramework.

    // Get number of Graphics Systems
    static uint32_t GetGSCount();
    static slString GetGSName(uint32_t);
    static slUID GetGSUID(uint32_t);
    // Create GS using slUID
    static slGS* SummonGS(slUID);
    // Create GS using it's name
    static slGS* SummonGS(const char*);
    // Both
    static slGS* SummonGS(slUID, const char*);
    

    Implementation

    uint32_t slFramework::GetGSCount()
    {
    	return (uint32_t)g_framework->m_gss.size();
    }
    
    slString slFramework::GetGSName(uint32_t i)
    {
    	return g_framework->m_gss[i]->GetName();
    }
    
    slUID slFramework::GetGSUID(uint32_t i)
    {
    	return g_framework->m_gss[i]->GetUID();
    }
    
    slGS* slFramework::SummonGS(slUID id)
    {
    	for (auto o : g_framework->m_gss)
    	{
    		if (CompareUIDs(o->GetUID(),id))
    			return o;
    	}
    	return 0;
    }
    
    slGS* slFramework::SummonGS(const char* _name)
    {
    	slString name(_name);
    	for (auto o : g_framework->m_gss)
    	{
    		slString o_name = o->GetName();
    		if (name == o_name)
    			return o;
    	}
    	return 0;
    }
    
    slGS* slFramework::SummonGS(slUID id, const char* _name)
    {
    	slString name(_name);
    	for (auto o : g_framework->m_gss)
    	{
    		if (CompareUIDs(o->GetUID(), id))
    		{
    			slString o_name = o->GetName();
    			if (name == o_name)
    				return o;
    		}
    	}
    	return 0;
    }
    

    Probably I don't need last method...

    Ok, and this is how to summon gs in app

    slGS* gs = slFramework::SummonGS(slFramework::GetGSUID(0));
    

    DLL history is done and now I need to implment SummonGS method for static version.

    I need to add gs pointers right in the code

    g_framework->m_gss.push_back(slGSD3D11_create());
    

    Everything is working.

    Other things

    I fixed slDLL methods. I don't need slDLLHandle*, I need just slDLLHandle

    // like this
    void slDLL::free(slDLLHandle library)
    

    Need to compare 2 slUIDs

    bool slFramework::CompareUIDs(const slUID& id1, const slUID& id2)
    {
    	const uint8_t* b1 = (const uint8_t*)&id1.d1;
    	const uint8_t* b2 = (const uint8_t*)&id2.d1;
    	for (int i = 0; i < 16; ++i)
    	{
    		if (b1[i] != b2[i])
    			return false;
    	}
    	return true;
    }
    
    Download