To do that I'm using a hack where you call some static methods inside another class, and I simply call them from the templated class, of course these methods are defined in the .cpp file, the problem is they can be called from other translation units as well, I would like to avoid that if possible.. any ideas?
Here's what I've tried so far:
- Make the methods private and friend the templated class
Doesn't work, I would have to template this other class as well if I did that, which would take me back to where I started
- Empty namespace
LNK2001
So right now I have them in another class, which is defined in the .cpp file, but as I've mentioned they can still be accessed from other files..
Code: Select all
#pragma once
#include "IResource.h"
#include <vector>
#include <type_traits>
class _detail
{
public:
static hResource CreateUniformBuffer(hResource bindingPoint, std::size_t size);
static void DeleteUniformBuffer(hResource bufferID);
static void RegisterShader(hResource shaderID, hResource bindingPoint, const char* block_name);
static void RegisterShader(std::vector<hResource> shaders, hResource bindingPoint, const char* block_name);
static void BindUniformBuffer(hResource bufferID);
static void FillUniformBuffer(hResource bufferID, std::size_t size, void* data);
};
template <typename _struct>
class UniformBlock sealed : public IResource
{
static hResource s_bindingPoint;
private:
hResource UBO_ID;
hResource bindingPoint;
char* _block_name;
std::size_t buffer_size;
public:
explicit UniformBlock(const char* block_name)
{
static_assert(!std::is_pointer<_struct>::value, "UniformBlock - Pointer data types are not allowed");
bindingPoint = s_bindingPoint;
++s_bindingPoint;
buffer_size = sizeof(_struct);
std::size_t str_length = strlen(block_name);
_block_name = new char[str_length + 1];
memcpy(_block_name, block_name, str_length);
_block_name[str_length] = '\0';
UBO_ID = _detail::CreateUniformBuffer(bindingPoint, buffer_size);
OutputInfo("Created uniform buffer ID: " << UBO_ID, 5);
}
~UniformBlock()
{
_detail::DeleteUniformBuffer(UBO_ID);
DeleteArrayHeap(_block_name);
OutputInfo("Deleted uniform buffer ID: " << UBO_ID, 5);
}
__forceinline void MapShaderBlock(hResource shader)
{
_detail::RegisterShader(shader, bindingPoint, _block_name);
}
__forceinline void MapShaderBlock(std::vector<hResource> shaders)
{
_detail::RegisterShader(shaders, bindingPoint, _block_name);
}
__forceinline void Update(_struct& data)
{
_detail::FillUniformBuffer(UBO_ID, buffer_size, static_cast<void *> (&data));
}
__forceinline void Bind() override
{
_detail::BindUniformBuffer(UBO_ID);
}
__forceinline hResource ID() const override
{
return UBO_ID;
}
};
template <typename _struct>
hResource UniformBlock<_struct>::s_bindingPoint = 0;