Skip to content

Instantly share code, notes, and snippets.

@louwers
Last active March 27, 2023 23:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save louwers/d8828498691c593b1bb6bf99e9411a2b to your computer and use it in GitHub Desktop.
Save louwers/d8828498691c593b1bb6bf99e9411a2b to your computer and use it in GitHub Desktop.
Shader registry using static template variable
$ g++ --std=c++17 -c maplibre.cc
$ ar rvs maplibre.a maplibre.o
$ g++ --std=c++17 main.cc maplibre.a
$ ./a.out
hello world
I am derived
#include "shader_registry.hpp"
#include "maplibre.hpp"
int main() {
init();
auto shader1 = ShaderRegistry::get<BaseShader>();
if (shader1) {
std::cout << shader1.value()->program();
}
ShaderRegistry::set<BaseShader>(std::make_shared<DerivedShader>());
auto shader2 = ShaderRegistry::get<BaseShader>();
if (shader2) {
std::cout << shader2.value()->program();
}
}
#include "maplibre.hpp"
void init() {
ShaderRegistry::set(std::make_shared<BaseShader>());
}
#include "shader_registry.hpp"
#pragma once
void init();
#include <iostream>
#include <string_view>
#include <optional>
#include <memory>
#include <type_traits>
#pragma once
class ShaderRegistry {
public:
// any instantiation of the variable template will create a new static data
// member, so the ShaderRegistry is a singleton, which is probably OK?
template<class ShaderType>
static inline std::optional<std::shared_ptr<ShaderType>> shaders;
template<class ShaderType>
static std::optional<std::shared_ptr<ShaderType>> get() {
return shaders<ShaderType>;
}
// this overload is used when setting a Shader while specifying its base class explicitly
template<class ShaderType, class ShaderTypeArg, typename = std::enable_if_t<std::is_base_of_v<ShaderType, ShaderTypeArg>>>
static void set(std::shared_ptr<ShaderTypeArg> shader) {
shaders<ShaderType> = shader;
}
template<class ShaderType>
static void set(std::shared_ptr<ShaderType> shader) {
shaders<ShaderType> = shader;
}
// a 'replace' member function can just ensure the optional is not null
};
struct BaseShader {
virtual std::string_view program() const {
return "hello world\n";
}
};
struct DerivedShader: public BaseShader {
virtual std::string_view program() const override {
return "I am derived\n";
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment