-#ifndef MSP_GL_BINDABLE_H_
-#define MSP_GL_BINDABLE_H_
-
-namespace Msp {
-namespace GL {
-
-template<typename T>
-class Bindable
-{
-protected:
- static const T *cur_obj;
-
- Bindable() { }
-
- 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;
-
-
-/**
-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. Optionally can restore the previous binding.
-*/
-class Bind
-{
-private:
- struct Base
- {
- virtual ~Base() { }
- };
-
- template<typename T>
- struct Binder1: Base
- {
- const T *obj;
-
- Binder1(const T *o):
- obj(o)
- {
- if(obj)
- obj->bind();
- else
- T::unbind();
- }
-
- ~Binder1()
- {
- if(obj)
- obj->unbind();
- }
- };
-
- template<typename T, typename U>
- struct Binder2: Base
- {
- const T *obj;
- const U *old;
-
- Binder2(const T *o, const U *l):
- obj(o),
- old(l)
- {
- if(obj)
- obj->bind();
- else
- T::unbind();
- }
-
- ~Binder2()
- {
- if(old)
- old->bind();
- else if(obj)
- obj->unbind();
- }
- };
-
- Base *binder;
-
-public:
- template<typename T>
- Bind(const T &o, bool r = false):
- binder(r ? create(&o, T::current()) : create(&o))
- { }
-
- template<typename T>
- Bind(const T *o, bool r = false):
- binder(r ? create(o, T::current()) : create(o))
- { }
-
- template<typename T>
- Bind(T *o, bool r = false):
- binder(r ? create(o, T::current()) : create(o))
- { }
-
-private:
- Bind(const Bind &);
- Bind &operator=(const Bind &);
-
-public:
- ~Bind() { delete binder; }
-
-private:
- template<typename T>
- Base *create(const T *o)
- { return new Binder1<T>(o); }
-
- template<typename T, typename U>
- Base *create(const T *o, const U *l)
- { return new Binder2<T, U>(o, l); }
-};
-
-} // namespace GL
-} // namespace Msp
-
-#endif