Code: Alles auswählen
// Globales interface
class MethodBinding
{
public:
MethodBinding(){}
virtual ~MethodBinding() { }
virtual void update(void) = 0;
};
// Template für ein Single-Value Parameterupdate
template <class ClassInstance, class BindingMethod>
class ValueBinding : public MethodBinding
{
protected:
typedef BindingMethod(ClassInstance::*Method)() const;
public:
/**
@brief Create a new value binding.
@throws brCore::brIllegalArgument exception if parameters are invalid.
@param parameter Reference to parent shader parameter which have to update.
@param instance The instance of the class containing the member method to bind.
@param binding The class method to bind (in the format '&class::method').
*/
ValueBinding(brShaderParameter* parameter, ClassInstance* instance, Method binding)
{
brCore::brAssert<brCore::brIllegalArgumentException>(parameter,
"[brShaderParameter]::ValueBinding: The brShaderParameter is invalid!");
brCore::brAssert<brCore::brIllegalArgumentException>(instance,
"[brShaderParameter]::ValueBinding: The class instance is invalid!");
m_parameter = parameter;
m_instance = instance;
m_binding = binding;
}
/**
@brief Calls the binding method to perform parameter value update.
@throws brCore::brIllegalStateException if shader parameter reference is invalid
*/
virtual void update(void) override
{
brCore::brAssert<brCore::brIllegalStateException>(m_parameter,
"[brShaderParameter]::ValueBinding:update: The brShaderParameter is invalid!");
m_parameter->setValue((m_instance->*m_binding)());
std::cout << "Value binding update called: " << m_parameter->getName() << std::endl;
}
protected:
brShaderParameter* m_parameter;
ClassInstance* m_instance;
Method m_binding;
};
Code: Alles auswählen
/** Reference to resolve build-in method binding*/
MethodBinding* m_method = nullptr;
template <class ClassInstance, class BindingMethod>
inline void brShaderParameter::bindValue(ClassInstance* instance, BindingMethod (ClassInstance::*Method)() const)
{
m_method = new ValueBinding<ClassInstance, BindingMethod>(this, instance, Method);
}
// Beispiel für die Erzeugung
parameter->bindValue(&renderer->m_renderState, &brRenderState::getWorldViewMatrix);
Code: Alles auswählen
template <class ClassInstance, class BindingMethod>
class ArrayBinding : public MethodBinding
{
typedef BindingMethod(ClassInstance::*Method)() const;
typedef unsigned int(ClassInstance::*Count)() const;
public:
ArrayBinding(brShaderParameter* parameter, ClassInstance* instance, Method binding, Count count)
{
brCore::brAssert<brCore::brIllegalArgumentException>(parameter,
"[brShaderParameter]::ValueBinding: The brShaderParameter is invalid!");
brCore::brAssert<brCore::brIllegalArgumentException>(instance,
"[brShaderParameter]::ValueBinding: The class instance is invalid!");
m_parameter = parameter;
m_instance = instance;
m_binding = binding;
m_count = count;
std::cout << "Array Binding performed" << m_parameter->getName() << std::endl;
}
void update(void) override
{
brCore::brAssert<brCore::brIllegalStateException>(m_parameter,
"[brShaderParameter]::ArrayBinding:update: The brShaderParameter is invalid!");
m_parameter->setValue((m_instance->*m_binding)(), (m_instance->*m_count)());
std::cout << "Array binding update called: " << m_parameter->getName() << std::endl;
}
private:
brShaderParameter* m_parameter;
ClassInstance* m_instance;
Method m_binding;
Count m_count;
};
Code: Alles auswählen
template <class ClassInstance, class BindingMethod>
inline void brShaderParameter::bindArray(ClassInstance* instance, BindingMethod (ClassInstance::*Method)() const, unsigned int (ClassInstance::*Count)() const)
{
std::cout << "BindArray called and ArrayBinding instance created" << std::endl;
m_method = new ArrayBinding<ClassInstance, BindingMethod>(this, instance, Method, Count);
}
// Beispiel
parameter->bindArray(&renderer->m_renderState, &brRenderState::getDirectionalLightDirections, &brRenderState::getNumberOfDirectionalLights);
Aufruf zum Update aufrufe:
Code: Alles auswählen
if(m_method != nullptr){
m_method->update();
}
Leider läuft aktuell mein Linux nicht, so das ich nicht mit Codeblocks debuggen kann. Und unter Windows will aktuell Codeblocks nicht mit dem MinGW64 zusammenarbeiten. So dass ich grad ohne Debugger da stehe ... Aber eigentlich müsste es doch so korrekt sein oder habe ich irgend etwas übersehen?