+++ /dev/null
-#ifndef MSP_GL_BINDABLE_H_
-#define MSP_GL_BINDABLE_H_
-
-namespace Msp {
-namespace GL {
-
-/**
-A helper class for single-point binding. Provides tracking of the currently
-bound object.
-*/
-template<typename T>
-class Bindable
-{
-protected:
- static const T *cur_obj;
-
- Bindable() { }
- ~Bindable() { if(cur_obj==this) T::unbind(); }
-
- static bool set_current(const T *obj)
- {
- if(obj==cur_obj)
- return false;
-
- cur_obj = obj;
- return true;
- }
-
-public:
- static const T *current() { return cur_obj; }
-};
-
-template<typename T>
-const T *Bindable<T>::cur_obj;
-
-
-/**
-A helper class for Bindables that revert to a default object on unbind.
-*/
-template<typename T>
-class BindableWithDefault: protected Bindable<T>
-{
- friend class Bindable<T>;
-
-protected:
- BindableWithDefault() { }
- ~BindableWithDefault() { if(this==&default_object()) Bindable<T>::set_current(0); }
-
-public:
- static const T *current()
- {
- if(!Bindable<T>::cur_obj)
- Bindable<T>::cur_obj = &default_object();
- return Bindable<T>::cur_obj;
- }
-
- static void unbind()
- {
- if(Bindable<T>::cur_obj)
- default_object().bind();
- }
-
- static const T &default_object()
- {
- static T obj;
- return obj;
- }
-};
-
-
-/**
-RAII class for binding things. Binds the thing upon construction and unbinds
-it upon destruction. If a null pointer is given, unbinds upon construction and
-does nothing upon destruction.
-*/
-class Bind
-{
-private:
- typedef void CleanupFunc(int);
-
- int slot;
- CleanupFunc *cleanup;
-
-public:
- template<typename T>
- Bind(T *o) { init(o); }
-
- template<typename T>
- Bind(const T *o) { init(o); }
-
- template<typename T>
- Bind(const T &o) { init(&o); }
-
- template<typename T, typename S>
- Bind(T *o, S s) { init(o, s); }
-
- template<typename T, typename S>
- Bind(const T *o, S s) { init(o, s); }
-
- template<typename T, typename S>
- Bind(const T &o, S s) { init(&o, s); }
-
-private:
- template<typename T>
- void init(const T *o)
- {
- cleanup = (o ? static_cast<CleanupFunc *>(&unbind<T>) : 0);
- slot = 0;
- if(o)
- o->bind();
- else
- T::unbind();
- }
-
- template<typename T, typename S>
- void init(const T *o, S s)
- {
- cleanup = (o ? static_cast<CleanupFunc *>(&unbind_from<T, S>) : 0);
- slot = s;
- if(o)
- o->bind_to(s);
- else
- T::unbind_from(s);
- }
-
-public:
- ~Bind()
- { if(cleanup) cleanup(slot); }
-
-private:
- template<typename T>
- static void unbind(int)
- { T::unbind(); }
-
- template<typename T, typename S>
- static void unbind_from(int s)
- { T::unbind_from(static_cast<S>(s)); }
-};
-
-
-/**
-Similar to Bind, but restores previous binding upon destruction.
-*/
-class BindRestore
-{
-private:
- typedef void CleanupFunc(const void *, int);
-
- const void *old;
- int slot;
- CleanupFunc *cleanup;
-
-public:
- template<typename T>
- BindRestore(T *o) { init(o); }
-
- template<typename T>
- BindRestore(const T *o) { init(o); }
-
- template<typename T>
- BindRestore(const T &o) { init(&o); }
-
- template<typename T, typename S>
- BindRestore(T *o, S s) { init(o, s); }
-
- template<typename T, typename S>
- BindRestore(const T *o, S s) { init(o, s); }
-
- template<typename T, typename S>
- BindRestore(const T &o, S s) { init(&o, s); }
-
-private:
- template<typename T>
- void init(T *o)
- {
- old = T::current();
- slot = 0;
- cleanup = (o!=old ? static_cast<CleanupFunc *>(&restore<T>) : 0);
- if(o)
- o->bind();
- else if(old)
- T::unbind();
- }
-
- template<typename T, typename S>
- void init(T *o, S s)
- {
- old = T::current(s);
- slot = s;
- cleanup = (o!=old ? static_cast<CleanupFunc *>(&restore_to<T, S>) : 0);
- if(o)
- o->bind_to(s);
- else if(old)
- T::unbind_from(s);
- }
-
-public:
- ~BindRestore()
- { if(cleanup) cleanup(old, slot); }
-
-private:
- template<typename T>
- static void restore(const void *o, int)
- {
- if(o)
- reinterpret_cast<const T *>(o)->bind();
- else
- T::unbind();
- }
-
- template<typename T, typename S>
- static void restore_to(const void *o, int si)
- {
- S s = static_cast<S>(si);
- if(o)
- reinterpret_cast<const T *>(o)->bind_to(s);
- else
- T::unbind_from(s);
- }
-};
-
-} // namespace GL
-} // namespace Msp
-
-#endif